JUnit与Mockito,EasyMock等嘲笑

我正在尝试在我正在测试的类中模拟一个对象的方法。

例如

class ClassToTest { public doSomething () { SomeObject a = new SomeObject (); a.doSomethingElse (); } } 

有没有办法模拟变量“a”的方法? 我想doSomethingElse在测试期间什么都不做。 我目前正在使用Mockito,但我对任何模拟框架持开放态度。

谢谢

是的,有一种方法,如下面的JMockit测试所示:

 public void testDoSomething(final SomeObject mock) { new ClassToTest().doSomething(); new Verifications() {{ mock.doSomethingElse(); }}; } 

无需重构测试代码以使用包装器,DI等; 简单地模仿你需要被嘲笑的东西。

当它被声明为局部变量时,不可能模仿引用“a”,就像你的情况一样。 您可以考虑将依赖项注入SomeObject,例如作为doSomething方法的参数。 这样,您可以在测试中注入SomeObject的模拟。

dependency injection的一个好处是提高了可测试性 。

通过一些重构,当然可以:

 class SomeObject { public void doSomethingElse() { } } class ClassToTest { private final SomeObject someObject; public void doSomething() { someObject.doSomethingElse(); } public ClassToTest(SomeObject someObject) { this.someObject = someObject; } } class Test { @Test public void testDoSomething() { SomeObject someObject = Mockito.mock(SomeObject.class); new ClassToTest(someObject).doSomething(); Mockito.verify(someObject, Mockito.atLeastOnce()).doSomethingElse(); } } 

我相信你可以为EasyMock 2.5或更早版本使用EasyMock Class Extensions ,显然它包含在3.0中。 有关您要执行的操作的信息,请参见上一页的这一部分 。 也就是说,我没有亲自尝试过这样做,所以我不知道它会有多好用。

如果你想在每个调用中有一个新实例,我建议用以下方式重构:

 class ClassToTest { public doSomething () { SomeObject a = getInstance(); a.doSomethingElse (); } protected SomeObject getInstance() { return new SomeObject(); } } 

然后,您可以创建一个扩展ClassToTest的测试类,覆盖getInstance()方法,其中一个提供模拟对象。

这当然只有在暴露getInstance()方法时才可行,所以如果该类是公共API的一部分,我不推荐它。 如果是这种情况,请考虑使用dependency injection提供工厂类。

 class ClassToTest { private SomethingElseInterface somethingElseDoer ; public ClassToTest(SomethingElseInterface somethingElseDoer) { this.somethingElseDoer = somethingElseDoer; } public doSomething () { somethingElseDoer.doSomethingElse(); } } 

在哪里使用它:

 SomethingElseInterface somethingElseDoer = ...; // in a test, this is where you mock it ClassToTest foo = new ClassToTest(somethingElseDoer); // inject through constructor foo.doSomething();