【问题标题】:Mocking a method that uses external classes, mockito模拟使用外部类的方法,mockito
【发布时间】:2014-07-22 10:12:00
【问题描述】:

我是 mockito 的新手,只是想了解它是如何工作的。

我有一个我想测试的方法。该方法实例化多个类以使用其方法。

例如

methodToTest{
 class1 c1 = new class1();
 class2 c2 = new class2();
 class3 c4 = new class3();

c1.method1;
c2.method2;
c3.method3;

more logic 

...

return result
}

我知道为了测试这个方法,我需要模拟这些类。这是否意味着我需要解耦它并将每个类作为参数传递给方法? 我想避免使用只有在模拟时才真正需要的大量参数的方法。

也许我错过了什么。

感谢您的见解。

【问题讨论】:

  • 这是否意味着我需要解耦它并将每个类作为参数传递给方法?这将是解决这个问题的好方法,是的。
  • 如果您的意思是“传入每个对象”,那么是的,这将是完全合理的做法。或者您可以使用工厂方法或工厂助手。在 Mockito 博客上查看 my article about this
  • 感谢 Keppil 和 David,我硬着头皮将模拟类添加为参数。我用一组较小的参数重载了该方法,以便客户端类在实时运行时不必实例化这些类。

标签: java unit-testing mockito


【解决方案1】:

我这里的标准解决方案是添加一个实例化类的方法:

public ClassToTest {
    methodToTest{
        class1 c1 = newClass1();
        ...
    }

    class1 newClass1() {
        return new Class1();
    }
}

新方法是protected 或包私有,我只是在我的单元测试中重写它以注入模拟:

@Test
public void testFoo() {
    ClassToTest inst = new ClassToTest() {
        class1 newClass1() {
            return new Class1(); // <--- you can mock here
        }            
    };
}

【讨论】:

  • 我喜欢!实际上,使用这种风格,你可以完全不使用 mockito。老派的嘲讽。有时它比 mockito 对应物要简单得多。
  • 嗨亚伦,感谢您的回复。我不认为我明白你的意思。如果您私下实例化新类,那么它不会被模拟,这意味着当您的测试方法ToTest 时,它将运行真实版本的 class1 对吗?如果您不介意,也许更深入的示例会有所帮助?
【解决方案2】:

您可以在创建新对象时实际模拟,而不是将类的不同对象传递给方法。 例如

Class1 class1 = Mockito.mock(Class1.class);
PowerMockito.whenNew(Class1.class).withNoArguments().thenReturn(class1);

在测试类的顶部写下这个注解

@RunWith(PowerMockRunner.class)
@PrepareForTest({Class1.class})
public class Class1Test {

----------- some code-------
}

点击链接 https://code.google.com/p/powermock/wiki/MockitoUsage13

希望这能解决您的问题。 如有疑问请咨询。

【讨论】:

  • 值得一提的是,您要在其中添加一个全新的库吗?这不是 Mockito。
  • 我自己也遇到了同样的问题。使用 PowerMockito 后,我认为它绝对值得。你可以做更多 Mockito 无法提供的事情。试一次。 Mockito 和 PowerMockito 可以一起工作,所以没有问题。这很简单。试试看吧。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
相关资源
最近更新 更多