当前位置: 首页 > 知识库问答 >
问题:

使用Mockito创建新类的实例时如何模拟异常

东方涛
2023-03-14

在一个方法中,我有一个异常被捕获,我想嘲笑它。

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

共有3个答案

谢旭
2023-03-14

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

将对象的创建放在一个单独的方法createBicycle()或单独的BicycleFactory中,并对其进行模拟。

程祯
2023-03-14

在这种情况下,您可以使用莫基托扩展,即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/power mock/source/browse/trunk/modules/module-test/mock ITO/JUnit 4/src/test/Java/samples/power mock ITO/JUnit 4/when new/when new test . Java

云锦
2023-03-14

你通常不会嘲笑构造函数。您可以使用像PowerMock这样的工具,但是我建议您不要这样做。

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

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

 类似资料:
  • 问题内容: 当我创建一个说类Employee的模拟对象时。它不调用Employee对象的构造函数。我知道Mockito在内部使用CGLIb和反射,创建了一个代理类,将该类扩展为模拟。如果未调用employee的构造函数,那么如何创建employee类的模拟实例? 问题答案: Mockito使用CGLib生成类对象。但是,要实例化此类对象,它使用Objenesis http://objenesis.

  • 我在github示例中发现了如何使用standart Mockito创建final类(BluetoOthgatt.class)实例: 但从Mockito常见问题: Mockito的局限性是什么 需要java 1.5+ 无法模拟最终类 ... 我检查了它是来自标准android-sdk的BluetoothGatt,所以它看起来像模拟的最终类。现在我尝试build project,以确保该测试工作正常

  • 问题内容: 我试图遵循这个非常相似的问题的答案中提供的示例,但是它对我不起作用。我收到以下错误消息: 我需要一个简单的模拟实例。我不需要模拟任何方法。 这是我要模拟的课程: 我有以下TestNG设置: 问题答案: 我通过扩展PowerMockTestCase类来完成这项工作,该类为TestNG处理此类事情:

  • 问题内容: 我有一个建设者: 在模仿器中模拟生成器将使我对每种方法都无效。因此,有没有一种简单的方法可以使生成器在每次调用函数时返回自身,而无需使用来模拟每个函数本身。 问题答案: 您可以使用RETURN_DEEP_STUBS模拟链接API。 如果您知道将调用您的构建器的确切顺序,那么以下是如何使用它的示例: 不幸的是,这不会为您提供一种模拟“所有各种生成器方法”的通用方法,以使它们始终返回此值,

  • 问题内容: 假设我有一个这样的课: 我想用模拟测试。因此,我创建了一个模拟对象,然后以这种方式调用方法进行测试: 但是,假设我有一个类似的类: 现在我无法将模拟作为参数传递,那么我该如何测试我的方法呢?有人可以举个例子吗? 问题答案: 从根本上讲,您正在尝试用替代实现替换私有字段,这意味着您违反了封装。您唯一的其他选择是重组类或方法,以使其更好地设计用于测试。 评论中有很多简短的答案,因此我在这里

  • 问题内容: 我有一个使用当前时间进行一些计算的函数。我想使用模仿器模拟它。 我要测试的课程示例: 我想要类似的东西: 可以嘲笑吗?我不想更改“已测试”的代码以进行测试。 问题答案: 正确的做法是重组代码,使其更具可测试性,如下所示。重组代码以消除对Date的直接依赖关系将使您可以为正常运行时和测试运行时注入不同的实现: