Java 如何在使用Mockito创建新类的实例时模拟异常
在一个方法中,我捕获了一个异常,我想模拟它 我知道如何使用mock.doSomething()模拟对象以引发异常,但我需要在类生成自身的新实例时引发远程异常Java 如何在使用Mockito创建新类的实例时模拟异常,java,junit,mocking,mockito,Java,Junit,Mocking,Mockito,在一个方法中,我捕获了一个异常,我想模拟它 我知道如何使用mock.doSomething()模拟对象以引发异常,但我需要在类生成自身的新实例时引发远程异常 transient Bicycle bike = null; public Bicycle getBicycle() { if (bike == null) { try { bike = new Bicycle(this); } catch (RemoteException
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文档,但没有发现任何有用的内容:
您通常不会模拟构造函数。你可以使用这样的工具,但我通常建议你不要 目前,如果您想控制在构建新的
自行车时会发生什么,那么您的代码实际上是不可测试的。建造一辆自行车
实际上是一项复杂的操作吗?例如,您可能需要一个BicycleFactory
,它可以作为依赖项传递到您的类中,然后您可以模拟BicycleFactory.createBicycle
或任何您称之为它的东西
构造函数类似于静态方法——当您使用它们时,您会紧密地绑定到所调用的特定代码;如果没有像PowerMock这样的方法,就没有干净的方法来注入其他行为。您的getBicycle()
现在至少可以做两件事。它检索(“获取”)一辆自行车
,并创建一辆自行车
。理想情况下,一个方法或类应该只做一件事,并且做得很好
将对象的创建放在一个单独的方法createBicycle()
或单独的BicycleFactory
中,并对其进行模拟。在这种情况下,您可以使用Mockito扩展PowerMock。它允许对构造函数进行模拟(请参阅)
在本例中,您将编写类似以下测试的内容:
@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);
}
}
更多示例可以在以下位置找到:我想我还没有说清楚,但是Bicycle是另一个类的实例,而不是该方法当前所在的类。该方法检索实例,但如果它为null,我想创建一个新实例。我不确定这是否会改变什么?@JohnVasiliou:不,一点也不。你仍然在调用构造函数——这根本不是你可以在测试中简单模仿的东西。在现实世界中,直接实例化依赖项是正确的做法。对于一个这样的例子,考虑一个业务服务类,它需要通过电子邮件发送通知;在Java中,一个众所周知的电子邮件API是,您通常在其中实例化email
子类(通常是SimpleEmail
),调用几个setter/adder,最后调用send()
方法。它简单、面向对象、易于单元测试。@Rogério:那么您将如何进行单元测试呢?在这个示例中,我希望有两个类:一个表示电子邮件本身(不会伪造),另一个表示能够发送电子邮件的电子邮件服务,这是伪造的。@JonSkeet您可以使用PowerMock,按照我对这个问题的回答中所示的方式,为业务服务类编写一个单元测试。还可以使用JMockitAPI(我开发的)编写一个更短、更简单的测试;如果你愿意,我可以在这里显示代码。请注意,您描述的电子邮件API与中的类似,具有值对象类SimpleEmailMessage
和无状态MailSender
服务接口。就个人而言,我更喜欢Apache API,它更简单、更面向对象。可能与@ChristofferHammarström重复这绝对不是重复。我写了前一个问题,我正在寻找两个不同的答案。