![](/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.