在一个方法中,我遇到了一个我想要模拟的异常。
我知道如何模拟一个使用mock.doSomething()来抛出异常的对象,但是当一个类创建一个新的实例时,我需要抛出一个远程异常。
transient Bicycle bike = null;
public Bicycle getBicycle() {
if (bike == null) {
try {
bike = new Bicycle(this);
} catch (RemoteException ex) {
System.out.println("No bikes found");
}
}
return bike;
}
我希望能够模拟try块中的所有内容,但我不明白你是如何模拟新类的创建的,具体如下:
bike = new Bicycle(this);
我尝试过许多不同的Mockito测试,例如:
Bicycle b = mock(Bicycle.class);
Mockito.doThrow(new RemoteException()).when(b = new Bicycle());
虽然我明白这会起作用但不起作用,但我想做类似的事情。
我已经阅读了Mockito文档并且没有找到任何有用的内容:
http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html
答案 0 :(得分:7)
您通常不会模拟构造函数。你可以使用像PowerMock这样的工具,但我通常建议你不要这样做。
目前,如果您想控制构建新Bicycle
时会发生什么,那么您的代码实际上是不可测试的。构建Bicycle
实际上是一个复杂的操作吗?也许你想要一个BicycleFactory
,它可以作为依赖项传递到你的类中,例如 - 然后你可以模拟BicycleFactory.createBicycle
或你称之为的任何东西。
构造函数就像静态方法 - 当你使用它们时,你会紧紧地绑定你正在调用的特定代码;没有像PowerMock那样的方法,没有干净的方式来注入其他行为。
答案 1 :(得分:3)
在这种情况下,您可以使用Mockito扩展程序PowerMock。它允许构造函数被模拟(参见https://code.google.com/p/powermock/wiki/MockConstructor)。
在这种情况下,您可以编写类似以下测试的内容:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ClassUnderTest.class, Bicycle.class})
public class ConstructorMockingTest
{
@Test
public void getBicycle()
{
ClassUnderTest tested = new ClassUnderTest();
whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException());
Bicycle bicycle = tested.getBicycle();
assertNull(bicycle);
}
}
答案 2 :(得分:0)
您的getBicycle()
现在至少做了两件事。它检索(“获取”)Bicycle
,并创建Bicycle
。理想情况下,方法或类只应做一件事,并且做得好。
将对象的创建放在单独的方法createBicycle()
或单独的BicycleFactory
中并模拟它。