当前位置: 首页 > 面试题库 >

用Mockito模拟单身人士

乜心思
2023-03-14
问题内容

我需要测试一些遗留代码,该遗留代码在方法调用中使用单例。该测试的目的是确保clas
sunder测试调用单例方法。我在SO上也看到过类似的问题,但是所有答案都需要其他依赖项(不同的测试框架)-不幸的是,我仅限于使用Mockito和JUnit,但这在如此流行的框架下应该是完全可能的。

单例:

public class FormatterService {

    private static FormatterService INSTANCE;

    private FormatterService() {
    }

    public static FormatterService getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new FormatterService();
        }
        return INSTANCE;
    }

    public String formatTachoIcon() {
        return "URL";
    }

}

被测课程:

public class DriverSnapshotHandler {

    public String getImageURL() {
        return FormatterService.getInstance().formatTachoIcon();
    }

}

单元测试:

public class TestDriverSnapshotHandler {

    private FormatterService formatter;

    @Before
    public void setUp() {

        formatter = mock(FormatterService.class);

        when(FormatterService.getInstance()).thenReturn(formatter);

        when(formatter.formatTachoIcon()).thenReturn("MockedURL");

    }

    @Test
    public void testFormatterServiceIsCalled() {

        DriverSnapshotHandler handler = new DriverSnapshotHandler();
        handler.getImageURL();

        verify(formatter, atLeastOnce()).formatTachoIcon();

    }

}

这个想法是配置可怕的单例的预期行为,因为被测类将调用它的getInstance,然后调用formatTachoIcon方法。不幸的是,这失败并显示一条错误消息:

when() requires an argument which has to be 'a method call on a mock'.

问题答案:

您的要求是不可能的,因为您的旧代码依赖于静态方法,getInstance()而Mockito不允许模拟静态方法,因此以下行将不起作用

when(FormatterService.getInstance()).thenReturn(formatter);

有两种方法可以解决此问题:

  1. 使用其他模拟工具,例如PowerMock,该工具可以模拟静态方法。

  2. 重构代码,以免依赖静态方法。我能想到的最小侵入性方法是通过向其DriverSnapshotHandler注入FormatterService依赖项的构造函数。该构造函数将仅在测试中使用,并且您的生产代码将继续使用实际的单例实例。

    public static class DriverSnapshotHandler {
    
    private final FormatterService formatter;
    
    //used in production code
    public DriverSnapshotHandler() {
        this(FormatterService.getInstance());
    }
    
    //used for tests
    DriverSnapshotHandler(FormatterService formatter) {
        this.formatter = formatter;
    }
    
    public String getImageURL() {
        return formatter.formatTachoIcon();
    }
    

    }

然后,您的测试应如下所示:

FormatterService formatter = mock(FormatterService.class);
when(formatter.formatTachoIcon()).thenReturn("MockedURL");
DriverSnapshotHandler handler = new DriverSnapshotHandler(formatter);
handler.getImageURL();
verify(formatter, atLeastOnce()).formatTachoIcon();


 类似资料:
  • 我需要测试一些遗留代码,这些代码在a方法调用中使用了单例。测试的目的是确保类sunder测试对singletons方法进行调用。我在SO上看到过类似的问题,但所有的答案都需要其他依赖项(不同的测试框架)--不幸的是,我仅限于使用Mockito和JUnit,但对于这样流行的框架,这应该是完全可能的。 单身人士: 正在测试的类: 单元测试: 这个想法是配置可怕的单例的预期行为,因为被测试的类将调用它的

  • 问题内容: 我对模拟还很陌生,并且我一直在尝试模拟实际内容(本质上仅在内存中创建一个虚拟文件),以便在任何时候都不会将任何数据写入磁盘。 我尝试过模拟文件和模拟尽可能多的属性的解决方案,然后还使用文件写入器/缓冲写入器将其写入,但是这些方法不能很好地工作,因为它们需要规范路径。有人找到了除此以外的解决方案,但我正在解决这个错误? 我一直在这样做: 任何想法或指导都将非常有帮助。在此之后的某个地方,

  • 我尝试测试一个发送jms消息的类,但无法模拟JmsTemplate JmsProducer.class: JmsProducerTest。类别: 当我运行这个测试用例时,它给了我:java。lang.IllegalArgumentException:对象不是声明类的实例 你对这个问题有什么想法吗?

  • 基类 在派生类中不应用组合和其他函数。如果是,我是否应用了错误的模式?我应该如何处理相同的?

  • 使用mockito模拟一个方法会确保永远不会调用被模拟的方法吗?我有一个主类,它包含一些我想为其编写单元测试的代码,还有一个单元测试类MainTest,它包含主类的单元测试。 eg: 源类: JUnit测试(使用mockito) 这项测试失败了。为什么?

  • 问题内容: 我想将构造函数模拟为方法。 在我的测试中,我想做这样的事情: 但是给我这个 错误 知道为什么吗? 问题答案: 您可以使用PowerMock模拟构造函数。 如果由于某种原因而无法使用PowerMock,则最可行的解决方案是将工厂注入到包含此方法的任何类中。然后,您将使用工厂创建对象并模拟工厂。