8

在一个方法中,我有一个要模拟的异常被捕获。

我知道如何使用 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

4

3 回答 3

7

您通常不会模拟构造函数。您可以使用PowerMock之类的工具,但我通常建议您不要这样做。

目前,如果您想控制Bicycle构建新代码时发生的情况,您的代码实际上是不可测试的。构造一个Bicycle实际上是一个复杂的操作吗?也许你想要一个BicycleFactory,例如,它可以作为依赖项传递到你的类中 -然后你可以模拟BicycleFactory.createBicycle或任何你称之为的东西。

构造函数就像静态方法——当你使用它们时,你会紧紧地绑定到你正在调用的特定代码;如果没有像 PowerMock 这样的方法,就没有干净的方法来注入其他行为。

于 2013-03-26T21:12:45.673 回答
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);
    }
}

更多示例可在以下位置找到:https ://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew /WhenNewTest.java

于 2013-03-27T11:56:53.443 回答
0

getBicycle()现在至少做了两件事。它检索(“获取”) a Bicycle,并创建一个Bicycle. 理想情况下,一个方法或类应该只做一件事,并且做得很好。

将对象的创建放在单独的方法中createBicycle()或单独BicycleFactory并模拟它。

于 2013-03-26T23:29:27.607 回答