在测试方法实现中使用模拟对象

时间:2016-01-27 08:31:52

标签: java unit-testing junit

我有一个问题。有一种使用其他对象实现的方法。我想测试一下这个不会使用其他对象调用的方法。

class Object1 {

    public void method1() {
        Object2 object2 = new Object2();
        String info = object2.getInfo();
        // ...
        // working with info, which I want to test
        // ...
    }

}

class Object1Test {
    @Test
    public void testMethod1() {
        Object1 object1 = new Object1();
        object1.method(); // want to run this method without invoking Object2
    }
}

你能帮我理解如何在junit中测试method1()我是否可以像Object2Mock一样模拟Object2的使用?

4 个答案:

答案 0 :(得分:1)

您需要对课程进行一些更改才能实现您的目标。

class Object1Test {
    @Test
    public void testMethod1() {
        Object1 object1 = new Object1();
        object1.setObject2(/* Pass your mocked object here */);
        object1.method(); // want to run this method without invoking Object2
    }
}

现在你只需要使用Object2的模拟对象调用你的setter方法。

Mockito

您还可以使用JMockgetInfo()来创建对象模拟。只要在Object2上调用Mockito.when(mockedObject2.getInfo()).thenReturn("Dummy Response"); ,您就可以告诉Mockito返回虚拟响应。例如,

{{1}}

答案 1 :(得分:1)

问题是您在方法中创建了一个新对象。您可以像这样重构代码:

class Object1 {

    public void method1() {
        Object2 object2 = getObject2();
        String info = object2.getInfo();
        // ...
        // working with info, which I want to test
        // ...
    }
    public Object2 getObject2() {
     return new Object2();
    }

使用上面的代码,现在您可以在测试getObject2()时模拟方法method1()

答案 2 :(得分:1)

不幸的是,您的代码不准备纯单元测试。

原因是Object1正在创建Object2的实例。没有办法轻易模拟新的陈述。

我建议你使用另一种方法(依赖注入,接收对象作为参数或在构造函数中)。

如果您无法更改Object1和Object2之间的关系,则可以使用PowerMock。

看看:https://github.com/jayway/powermock/wiki/MockConstructor

但请注意,只有在没有替代方案时才应使用PowerMock。使用PowerMock表示设计不好。

答案 3 :(得分:0)

应应用依赖项注入:

public class Object1 {
    Object2 object2;

    public Object1(Object2 object2) {
        this.object2 = object2;
    }

    public void method1() {
        String info = object2.getInfo();
    }

}

并处于测试状态:

import org.junit.runner.RunWith;
import org.mockito.*;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.junit.*;

@RunWith(MockitoJUnitRunner.class)
public class Object1Test {
    Object1 object1;
    @Mock
    Object2 mockedObject2;

    @Before
    public void setUp(){
        object1 = new Object1(mockedObject2);
    }

    @Test
    public void testMethod1() {
        Mockito.when(mockedObject2.getInfo()).thenReturn("Mocked response");

        object1.method1();
    }
}

在您仅提供PowerMockito的代码中是解决方案,但强烈建议不要这样做。