Mockito.mockConstruction 不 return 模拟对象
Mockito.mockConstruction does not return the mocked object
我不想再使用 powermock 了。因为 junit5 开始模拟静态 classes。所以我试图摆脱 powermock 方法。
如您所知,您可以使用 whenNew 关键字创建 class 的实例。所以我决定使用“mockConstruction”。但是 mockConstruction 不会 return 模拟对象。它不会进入 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);
})) {
}
}
如有任何帮助,我们将不胜感激。
我想我和你有同样的问题,希望有人能解决我们的问题。
在我的例子中,我也想得到一个 return 对象,比如 PowerMock.whenNew().withArguments().thenReturn(someThing),我尝试了很多次但都失败了。
我认为 mockConstruction 只是可以模拟他们的行为,不能像 powerMock 那样验证他们的结果,而且我找不到任何文章或答案。
下面是我的 post link :
您可以通过 MockedConstruction.constructed() 方法访问在对象实例化期间创建的模拟。它表示在每个构造函数执行后创建的模拟集合。如果您的对象将被实例化 3 次 MockedConstruction<T>.constructed()
将为每个实例化 return 3 个不同的模拟对象。
根据文档MockedConstruction<T>
Represents a mock of any object construction of the represented type.
Within the scope of the mocked construction, the invocation of any
interceptor will generate a mock which will be prepared as specified
when generating this scope. The mock can also be received via this
instance.
下面带有注释的简单实现显示了如何从 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);
}
}
我不想再使用 powermock 了。因为 junit5 开始模拟静态 classes。所以我试图摆脱 powermock 方法。
如您所知,您可以使用 whenNew 关键字创建 class 的实例。所以我决定使用“mockConstruction”。但是 mockConstruction 不会 return 模拟对象。它不会进入 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);
})) {
}
}
如有任何帮助,我们将不胜感激。
我想我和你有同样的问题,希望有人能解决我们的问题。
在我的例子中,我也想得到一个 return 对象,比如 PowerMock.whenNew().withArguments().thenReturn(someThing),我尝试了很多次但都失败了。 我认为 mockConstruction 只是可以模拟他们的行为,不能像 powerMock 那样验证他们的结果,而且我找不到任何文章或答案。 下面是我的 post link :
您可以通过 MockedConstruction.constructed() 方法访问在对象实例化期间创建的模拟。它表示在每个构造函数执行后创建的模拟集合。如果您的对象将被实例化 3 次 MockedConstruction<T>.constructed()
将为每个实例化 return 3 个不同的模拟对象。
根据文档MockedConstruction<T>
Represents a mock of any object construction of the represented type. Within the scope of the mocked construction, the invocation of any interceptor will generate a mock which will be prepared as specified when generating this scope. The mock can also be received via this instance.
下面带有注释的简单实现显示了如何从 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);
}
}