![](/img/trans.png)
[英]How to mock a non static method of a class whose instance is passed as argument?
[英]How to mock an instance created by a static method?
我正在测试看起来像这样的遗留代码。
class Converter {
static String convert() {
SubConverter.subConvert();
}
}
class SubConverter {
static String subConvert() {
Generator generator = new Generator();
return generator.generate();
}
}
我的目标是测试Converter.convert
,模拟generator.generate()
。
测试类如下所示:
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
class ConverterTest {
@Mock
Generator generatorMock;
@Test
public void convertTest(){
MockitoAnnotations.openMocks(this);
Mockito.when(generatorMock.generate()).thenReturn("123");
Converter.convert();
// some assertions
}
}
使用Generator.generate()
的实际实现而不是模拟。
我试过了:
import org.mockito.InjectMocks;
@InjectMocks
Converter converterWithMock;
,测试converterWithMock.convert()
,结果相同。
我已经尝试过使用 PowerMockito,但我无法让它工作(也许我以错误的方式使用它)。
这样做的正确方法是什么?
使用junit-jupiter 5.8.2和mockito 4.3.1 。
您需要模拟Generator
类的构造函数。
解决方案 1:使用 Mockito(主要优先)
Mockito 从 3.5 版本开始支持模拟构造。 文档
将mockito-inline添加到您的依赖项中。 它提供了在构造函数调用上生成模拟的能力。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
模拟构造函数。
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
class ConverterTest {
@Test
public void convertTest(){
//create mock for Generator class constructor
try (MockedConstruction<Generator> mockedGenerator = Mockito.mockConstruction(Generator.class,
(mock, context) -> {
when(mock.generate()).thenReturn("123");
})) {
//execute Converter class under the test
String result = Converter.convert();
//ensure that constructor was executed
Assertions.assertFalse(mockedGenerator.constructed().isEmpty());
//ensure the generate method was executed
verify(mockedGenerator.constructed().get(0), times(1)).generate();
//verify return value
Assertions.assertEquals("123", result);
}
}
}
解决方案 2:使用 PoserMock
PowerMock不支持 JUnit 5 ,只有 Junit 4。
通过 PowerMock 模拟构造函数的示例
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(SubConverter.class)
public class ConverterTest {
@Mock
Generator generatorMock; //create Mock
@Test
public void convertTest() throws Exception {
//configure Mock
Mockito.when(generatorMock.generate()).thenReturn("123");
//return mock when constructor is executing
PowerMockito.whenNew(Generator.class).withNoArguments().thenReturn(generatorMock);
//perform Converter under the test
String result = Converter.convert();
//check return value
Assert.assertEquals("123", result);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.