如何模拟每个类实例的方法

时间:2018-05-09 17:08:27

标签: java android

我有使用其他对象new MyClass()的方法的方法。我单独测试提到的类(其他测试)。但是测试中每个实例所需类的模拟方法是否可行?我需要MyClass的行为方法。

经过测试的课程:

public class A {

  public String methodA(int a, int b){
    MyClass object = new MyClass(a, b);
    String a = object.method();
    // complex computation
    return "result";
  }
}

这样的事情:

when(new MyClass.method()).thanReturn("abcd")

3 个答案:

答案 0 :(得分:1)

如果要替换类中方法的功能, 在单元测试期间, 您为该类创建一个包装器并替换包装器中的方法。

如果您使用Mockito, 您可以通过在类上创建Spy来为类创建包装器。 一旦你有间谍, 你可以使用Mockito的行为功能(当... thenReturn)来替换方法。

这是一个简单的例子:

@Spy
private MyClass classToTest;

@Before
public void preTestSetup()
{
    MockitoAnnotations.initMocks(this);

    doReturn("blammy").when(classToTest).getHooty();
}

@Test
public void someTest()
{
    // This prints "blammy".
    System.out.println(classToTest.getHooty());
}

修改 既然问题已经改变了, 答案也需要改变。

如@GhostCat答案所述, 您无法使用Mockito更改new的返回值。 我不会这样做。 代替, 在像你这样的情况下, 我会创建一个MyClassFactory(或建设者,无论如何) 这会创建MyClass的实例。 我会在课程MyClassFactory中添加A个实例。 然后我会注入一个MyClassFactory,它返回MyClass的模拟实例。

答案 1 :(得分:1)

基本上"直接"答案是使用PowerMock或JMockit等框架。这些允许你拦截"调用new()然后返回一个mock。 Mockito无法做到这一点。

但首选方法是不直接在生产代码中调用new。相反,你会研究依赖注入机制。换句话说:您可以更改生产,而不是更改模拟框架,以便更容易测试。

添加更多详细信息,以显示必要我的答案是什么。

when(new MyClass.method()).thanReturn("abcd")

您不明白的是when()适用于模拟对象。您错误地认为when()可以在任何 MyClass对象上调用method()时神奇地知道。但这是错误的。 when()只知道当你when(someMockedMyClassInstance) ...它必须"监控"呼叫转到那个特定的someMockedInstanceObject

除此之外,new()不是常规方法。你不能简单地嘲笑它。如上所述,您只剩下两个选项:

  • 您使用PowerMock拦截对new的调用。在那里,你提供了一个模拟实例(而不是new()创建一个真正的新对象。而现在你有一个模拟对象,你可以控制该对象的行为
  • 您通过使用替代方法为生产代码提供所需对象,从而消除了生产代码中对new()的调用。有关 one 的方法,请参阅this以了解如何使用@InjectMocks执行此操作。

答案 2 :(得分:0)

@Mock
MyClass myClass;

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

@Test
public void myClassTest() {
    when(myClass.classMethod()).thanReturn("abc")
}

如果你正在使用Mockito,试试这个!