注入内联 Mockito 静态方法
Inject inline Mockito static methods
我正在使用 JUnit4 测试 class 并且目标 class 使用依赖静态方法来创建对象,这里是目标 class 中的相关代码片段:
private static final Dependency DEPENDENCY_CLIENT = Dependency.getInstance();
我知道从 Mockito 的 3.4.0 版本开始,增加了模拟静态方法的能力,例如,我可以这样做:
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
mocked.when(Dependency::getInstance).thenReturn(dependency);
Dependency test = Dependency.getInstance();
mocked.verify(Dependency::getInstance);
}
dependency
变量只是 class 的简单模拟版本。
但是,我要测试的 class 在其构造函数中进行了此调用,所以有没有办法让我的目标 class 在期间调用模拟的 getInstance()
方法它的初始化?
我不确定你遇到了什么问题。下面的代码对我有用(我使用的是 JUnit 5,但这应该没什么区别)
@ExtendWith(MockitoExtension.class)
public class MockEg {
static class Dependency {
public static Dependency getInstance() {
return new Dependency();
}
public String getMessage() {
return "I am not a mock";
}
}
static class ClassToTest {
private final Dependency dependency;
public ClassToTest() {
this.dependency = Dependency.getInstance();
}
public String getDependencyMessage() {
return dependency.getMessage();
}
}
@Test
public void aTest() {
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
Dependency dependency = mock(Dependency.class);
when(dependency.getMessage()).thenReturn("I am a mock");
mocked.when(Dependency::getInstance).thenReturn(dependency);
ClassToTest c = new ClassToTest();
assertThat(c.getDependencyMessage(), Matchers.is("I am a mock"));
mocked.verify(Dependency::getInstance);
}
}
}
处理这种情况的正确方法是将 class 与 static
分离,方法是引入一个可以模拟的接口:
interface DependencyProvider {
Dependency getDependency();
}
class ClassToTest2 {
private final DependencyProvider dependencyProvider;
public ClassToTest2(DependencyProvider dependencyProvider) {
this.dependencyProvider = dependencyProvider;
}
public String getDependencyMessage() {
return dependencyProvider.getDependency().getMessage();
}
}
我正在使用 JUnit4 测试 class 并且目标 class 使用依赖静态方法来创建对象,这里是目标 class 中的相关代码片段:
private static final Dependency DEPENDENCY_CLIENT = Dependency.getInstance();
我知道从 Mockito 的 3.4.0 版本开始,增加了模拟静态方法的能力,例如,我可以这样做:
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
mocked.when(Dependency::getInstance).thenReturn(dependency);
Dependency test = Dependency.getInstance();
mocked.verify(Dependency::getInstance);
}
dependency
变量只是 class 的简单模拟版本。
但是,我要测试的 class 在其构造函数中进行了此调用,所以有没有办法让我的目标 class 在期间调用模拟的 getInstance()
方法它的初始化?
我不确定你遇到了什么问题。下面的代码对我有用(我使用的是 JUnit 5,但这应该没什么区别)
@ExtendWith(MockitoExtension.class)
public class MockEg {
static class Dependency {
public static Dependency getInstance() {
return new Dependency();
}
public String getMessage() {
return "I am not a mock";
}
}
static class ClassToTest {
private final Dependency dependency;
public ClassToTest() {
this.dependency = Dependency.getInstance();
}
public String getDependencyMessage() {
return dependency.getMessage();
}
}
@Test
public void aTest() {
try (MockedStatic<Dependency> mocked = mockStatic(Dependency.class)) {
Dependency dependency = mock(Dependency.class);
when(dependency.getMessage()).thenReturn("I am a mock");
mocked.when(Dependency::getInstance).thenReturn(dependency);
ClassToTest c = new ClassToTest();
assertThat(c.getDependencyMessage(), Matchers.is("I am a mock"));
mocked.verify(Dependency::getInstance);
}
}
}
处理这种情况的正确方法是将 class 与 static
分离,方法是引入一个可以模拟的接口:
interface DependencyProvider {
Dependency getDependency();
}
class ClassToTest2 {
private final DependencyProvider dependencyProvider;
public ClassToTest2(DependencyProvider dependencyProvider) {
this.dependencyProvider = dependencyProvider;
}
public String getDependencyMessage() {
return dependencyProvider.getDependency().getMessage();
}
}