java 模拟自定义对象

java mocking custom objects

public class MainClass  {

    public void makeCall() {
        CustomObject obj = new CustomObject();
        obj.testMethod();
    }
}

我想对 makeCall() 进行单元测试。所以我必须模拟上面示例中的 CustomObject 。当我模拟对象 mock(CustomObject.class) 时,我使用 Mockito 作为模拟 framework.But。 makeCall() 方法总是调用实际对象而不是模拟的 one.Is 无论如何模拟本地对象。请帮忙

简短的回答是否定的。你可以做的是将本地对象重构为一个字段或一个参数,如下所示:

public class MainClass  {

    public void makeCall(CustomObject obj) {
        obj.testMethod();
    }
}

您当前的程序违反了Dependency Inversion Principle,因此建议您重构它。

如果您使该字段成为一个实例变量,如果您有一个 setter 或您根据构造函数参数对其进行初始化,则可以轻松模拟它。后者的例子:

public class MyTest {

    @Mock
    private CustomObject objMock;

    private MyClass objToTest;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        objToTest = new MyClass(objMock);
    }

}

不适用于 Mockito 本身,不。您必须修改代码,以便从另一个来源创建自定义对象并模拟该来源。

这是我推荐的...但是确实存在 PowerMockito:

的解决方案
final CustomObject obj = mock(CustomObject.class);

PowerMockito.whenNew(CustomObject.class).withNoArguments()
    .thenReturn(obj);

不过,呃。重构你的代码。你会因此变得更好。

您的 MainClass 的单元测试友好版本应该 CustomObject 注入,例如:

public class MainClass  {
    private CustomObject customObject = new CustomObject();  // a default one if none is provided

    public void setCustomObject(CustomObject customObject) {
        this.customObject = customObject;
    }

    public void makeCall() {
        this.customObject.testMethod();
    }
}

您的测试将如下所示:

CustomObject mockCustomObject = mock(CustomObject.class);
when(mockCustomObject.testMethod()).thenReturn(...);

MainClass sut = new MainClass();
sut.setCustomObject(mockCustomObject);

sut.makeCall();

verify(mockCustomObject).testMethod();

加上Mockito的注解,可以进一步简化为:

public class MyClassTest {
    @InjectMocks
    private MainClass mainClass;

    @Mock
    private CustomObject mockCustomObject;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);  // or use mockito runner
    }

    @Test
    public void testMakeCall() {
        when(mockCustomObject.testMethod()).thenReturn(...);
        mainClass.makeCall();
        verify(mockCustomObject).testMethod();
    }
}