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

3

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

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个回答

1

为了达到你想要的目的,你需要对你的类进行一些修改。

class Object1 {
    private Object2 object2 = new Object2();

    /* Setter Method for Object2 */
    public void setObject2(Object2 object2) {
         this.object2 = object2;
    }

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

现在,您只需要使用Object2的模拟对象调用setter方法即可。
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
    }
}

你还可以使用MockitoJMock来创建对象模拟。你只需告诉Mockito当在Object2上调用getInfo()时返回虚假响应即可。例如,
Mockito.when(mockedObject2.getInfo()).thenReturn("Dummy Response");

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();
    }

通过上面的代码,现在你可以在测试method1()时模拟方法getObject2()


1
你错了。你不应该嘲笑你试图测试的同一个类。Object2的创建应该在Object1之外。 - jfcorugedo
我们可以在Object1类中使用一个setter方法来设置测试类中的模拟对象Object2 - user2004685
@jfcorugedo,我们不应该嘲笑正在进行单元测试的方法。在我看来,模拟同一类中的其他方法是完全有效的。它们将在它们自己的单元测试中得到覆盖。 - Manish

1

很遗憾,你的代码不适合进行纯单元测试。

原因是Object1正在创建Object2的实例。没有简便的方法来模拟一个新语句。

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

如果你不能改变Object1和Object2之间的关系,你可以使用PowerMock。

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

但请注意,只有在没有其他选择的情况下才应该使用PowerMock。使用PowerMock表示设计有问题。


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是解决方案,但强烈不建议使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接