我不想再使用 powermock 了。因為 junit5 開始模擬靜態類。所以我試圖擺脫 powermock 方法。
如您所知,您可以使用 whenNew 關鍵字創建類的實體。所以我決定使用“mockConstruction”。但是 mockConstruction 不回傳模擬物件。它不會進入 try 塊。
這是我的 BeforeEach 方法:
@BeforeEach
void setUp() {
partUnlinkService =
spy(new PartVideoUnlinkService(part1, part2,
part3));
}
這是我的測驗方法:
@Test
void shouldThrowException() throws Exception {
//given
UrlLinkDto urlLinkDto =
UrlPartLinkDto.builder().callId("333").videoId("5555544").build();
ArgumentCaptor<UrlPartLinkDto> argumentCaptor = ArgumentCaptor.forClass(UrlPartLinkDto.class);
//when
try (MockedConstruction<ObjectMapper> ignoredVariable = mockConstruction(ObjectMapper.class,
(objectMapper, context) -> {
//then
partUnlinkService.unlink(urlLinkDto, false);
verify(partLogCheckService, times(1)).checkForExistingVideo(
urlLinkDto.getVideoId());
verify(objectMapper, times(1)).writeValueAsString(argumentCaptor.capture());
Throwable throwable =
catchThrowable(() -> objectMapper.writeValueAsString(argumentCaptor.capture()));
assertThat(throwable).isInstanceOf(JsonProcessingException.class);
})) {
}
}
任何幫助,將不勝感激。
uj5u.com熱心網友回復:
您可以通過MockedConstruction.constructed()方法訪問在物件實體化期間創建的模擬。它表示在每個建構式執行后創建的模擬集合。如果您的物件將被實體化 3 次MockedConstruction<T>.constructed(),則每次實體化都會回傳 3 個不同的模擬物件。
根據檔案MockedConstruction<T>
表示所表示型別的任何物件構造的模擬。在模擬構造的范圍內,任何攔截器的呼叫都將生成一個模擬,該模擬將在生成此范圍時按照指定的方式進行準備。也可以通過此實體接收模擬。
帶有以下注釋的簡單實作顯示了如何從中獲取模擬MockedConstruction并驗證它們:
public class A {
private final String test;
public A(String test) {
this.test = test;
}
public String check() {
return "checked " this.test;
}
}
public class TestService {
public String purchaseProduct(String param) {
A a = new A(param);
return a.check();
}
}
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
public class ConstructorMockTest {
private MockedConstruction<A> mockAController;
@BeforeEach
public void beginTest() {
//create mock controller for all constructors of the given class
mockAController = Mockito.mockConstruction(A.class,
(mock, context) -> {
//implement initializer for mock. Set return value for object A mock methods
when(mock.check()).thenReturn(" Constructor Mock A ");
});
}
@Test
public void test() {
//each instantiation of class A will return new mock, which initialized by initializer from beginTest method
//new mock will be stored to mockAController.constructed() collection of mocks
A aObject = new A("test");
//ensure that method check() returns mocked value
Assertions.assertEquals(aObject.check(), " Constructor Mock A ");
//get just created mock for class A from controller. It will be first element of mockAController.constructed() collection
A aMock = mockAController.constructed().get(0);
//ensure that we get correct mock from mock controller, that it is equal from new created object
Assertions.assertEquals(aMock, aObject);
//verify that check method was executed on Mock
verify(aMock, times(1)).check();
//create new A object, new mock created and stored to mockAController.constructed()
A aObject2 = new A("test");
//ensure that method check() returns mocked value
Assertions.assertEquals(aObject2.check(), " Constructor Mock A ");
//get just created mock for class A from controller, it will be second object from constructed collection
A aMock2 = mockAController.constructed().get(1);
//ensure that we get correct mock from mock controller, that it is equal from just created A object
Assertions.assertEquals(aObject2, aMock2);
//verify that check method was executed on Mock
verify(aMock2, times(1)).check();
//Example of testing service which creates A object
TestService service = new TestService();
String serviceResult = service.purchaseProduct("test");
//ensure that service returned value from A mock
Assertions.assertEquals(serviceResult, " Constructor Mock A ");
//get just created mock for class A from controller, it will be third object from constructed collection
A aMock3 = mockAController.constructed().get(2);
//verify that check method was executed on Mock
verify(aMock3, times(1)).check();
}
@AfterEach
public void endTest() {
mockAController.close();
}
}
讓我們重寫你的測驗。我沒有完整的代碼,但我會嘗試創建一個帶有注釋的示例:
@Test
void shouldThrowException() throws Exception {
//given
UrlLinkDto urlLinkDto =
UrlPartLinkDto.builder().callId("333").videoId("5555544").build();
ArgumentCaptor<UrlPartLinkDto> argumentCaptor = ArgumentCaptor.forClass(UrlPartLinkDto.class);
try (MockedConstruction<ObjectMapper> objectMapperMockedConstruction = mockConstruction(ObjectMapper.class,
(objectMapper, context) -> {
//initialize ObjectMapper mock to throw exception when argumentCaptor will come to writeValueAsString method
doThrow(JsonProcessingException.class).when(objectMapper).writeValueAsString(argumentCaptor.capture());
})) {
//execute service for testing and catch exception
Throwable throwable = catchThrowable(() -> partUnlinkService.unlink(urlLinkDto, false));
//verify that inner service was executed
verify(partLogCheckService, times(1)).checkForExistingVideo(urlLinkDto.getVideoId());
//verify that ObjectMapper was instantiated
Assertions.assertEquals(1, objectMapperMockedConstruction.constructed().size());
//get mock of ObjectMapper which was instantiated during service execution
ObjectMapper objectMapper = objectMapperMockedConstruction.constructed().get(0);
//verify that writeValueAsString was executed
verify(objectMapper, times(1)).writeValueAsString(argumentCaptor.capture());
//check that exception is correct
assertThat(throwable).isInstanceOf(JsonProcessingException.class);
}
}
uj5u.com熱心網友回復:
我想我和你有同樣的問題,希望有人能解決我們的問題。
就我而言,我還想獲得一個回傳物件,例如 PowerMock.whenNew().withArguments().thenReturn(someThing),我嘗試了很多次但都失敗了。我認為 mockConstruction 只能模擬他們的行為,不能像 powerMock 那樣驗證他們的結果,而且我找不到任何文章或答案。以下是我的帖子鏈接:
Junit 5 使用 mockConstruction().withSetting().useConstructor() 而不是 PowerMock.whenNew().withArguments()
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/482310.html
上一篇:如果使用FilterRegistrationBean,為什么Autowired不能在Filter內部作業?[復制]
