gpt4 book ai didi

java - 用 mockito 模拟单例

转载 作者:IT老高 更新时间:2023-10-28 20:27:45 25 4
gpt4 key购买 nike

我需要测试一些在方法调用中使用单例的遗留代码。测试的目的是确保类 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 添加一个构造函数,该构造函数注入(inject)一个 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();

关于java - 用 mockito 模拟单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38914433/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com