简体   繁体   English

Java:对外部库的模拟调用以测试构造函数

[英]Java: mock call to external library to test constructor

I'm trying to unit test ClassA(String) constructor of following ClassA class: 我正在尝试对以下ClassA类的ClassA(String)构造函数进行单元测试:

import ExternalObject;

class ClassA{

    private ExternalObject externalObject;

    public ClassA() {
        super();
    }

    public ClassA(String string) {
        super();
        this.externalObject = new ExternalObject().parseString(string);
    }
}

I want to mock the new ExternalObject().parseString(string) call and stub it with a sample ExternalObject object. 我想模拟new ExternalObject().parseString(string)调用,并使用示例ExternalObject对象对其进行存根。

I've looked into Mockito, but it seems this task isn't possible with Mockito because: 我已经研究了Mockito,但是看来Mockito无法完成此任务,因为:

  • Mockito can only mock methods, not statements inside methods. Mockito只能模拟方法,而不能模拟方法中的语句。
  • Mockito requires object to be created before mocking them. Mockito要求在模拟对象之前先创建对象。 Mockito needs an instance of the class before you can begin mocking . Mockito需要类的实例,然后才能开始进行模拟 So even if I put new ExternalObject().parseString() call in a separate method in ClassA class, I can't call it without a ClassA instance. 因此,即使我将new ExternalObject().parseString()调用放在ClassA类的单独方法中,也不能在没有ClassA实例的情况下调用它。

Is it possible to do this in Mockito (or any other mocking library) without rewriting a lot of code? 是否可以在Mockito(或任何其他模拟库)中执行此操作而无需重写大量代码? I'm open to small code changes to make it more test-friendly. 我愿意进行小的代码更改,以使其更易于测试。

In order to mock the ExternalObject you have to be able to supply the instance of ExternalObject which is used in your test flow. 为了模拟ExternalObject您必须能够提供在测试流程中使用的ExternalObject实例。

That's going to be difficult as long as the ExternalObject is created inside public ClassA(String string) . 只要 public ClassA(String string) 内部创建ExternalObject这将很困难。

In order to make your ClassA more testable you'll need to be able to provide an instance of ExternalObject when constructing ClassA . 为了使您的ClassA更具可测试性,您需要在构造ClassA时提供一个ExternalObject实例。

For example: 例如:

class ClassA{

    private ExternalObject externalObject;

    public ClassA() {
        super();
    }

    public ClassA(ExternalObject externalObject, String string) {
        super();
        this.externalObject = externalObject.parseString(string);
    }
}

This can be then tested as follows: 然后可以如下进行测试:

public class ClasssATest {

    @Test
    public void someTest() {
        String input = "a string";
        ExternalObject externalObject = Mockito.mock(ExternalObject.class);
        Mockito.when(externalObject.parseString(eq(input))).thenReturn(externalObject);

        ClassA sut = new ClassA(externalObject, input);
        ...
    }
}

The key point here is: inject the external dependency into your class. 这里的关键点是:将外部依赖项注入您的类中。 Once you make this change, testing becomes much easier and, more generally, this approach makes it easier to change system behaviour by swapping in/out implementations of that external dependency. 进行更改后,测试将变得更加容易,并且更一般地说,通过交换该外部依赖项的实现,此方法可以更轻松地更改系统行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM