spring - Mockito @Spy 在定义模拟行为时调用真实方法
问题描述
我有一个由控制器和服务层组成的常见 Spring Boot 应用程序。不涉及数据库,因为我使用另一个 rest api 来存储数据。
现在我想要我的控制器,因此我想部分地模拟我的服务。部分原因是我有一种方法可以接受 dto 并将其转换为我的业务模型。我知道这也可以通过业务模型的构造函数来解决,但无论如何我遇到了以下问题:
代码
控制器
@RestController
public class RegistrationController {
@Autowired
private UserRegistrationService userRegistrationService;
@PostMapping(value = "/user", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<UserId> createUser(@RequestBody @Valid UserDto userDto) {
KeycloakUserRepresentation keycloakUserRepresentation = userRegistrationService.convertUserDtoToKeycloakUserRepresentation(userDto);
UserId userId = userRegistrationService.createNewUser(keycloakUserRepresentation);
return new ResponseEntity<>(userId,HttpStatus.CREATED);
}
测试
@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith({RestDocumentationExtension.class})
@AutoConfigureRestDocs
class RegistrationControllerRegistrationTest {
private static final UserDto testUsertDto = new UserDto();
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Spy
private UserRegistrationServiceImpl userRegistrationService;
在我的测试方法中,我定义:
doReturn(testUserId).when(userRegistrationService).createNewUser(any(KeycloakUserRepresentation.class));
问题:
我希望虽然在我的测试中没有定义 doSomething,但将 userDto 转换为 keycloak 表示是由原始方法完成的。当我在控制器中调试时,这似乎起作用,keycloakUserRepresentation 具有正确的值。问题是在下一步中
createNewUser
方法没有被存根/模拟。执行了原始方法,因此我的测试失败了。我想要的是,当我在我的测试用例中提供一个 doSomething 方法时,我希望原始方法被模拟。
解决方案
当我在控制器中调试时,这似乎起作用,keycloakUserRepresentation 具有正确的值。
它起作用了,因为豆子根本没有被监视。尽管@Spy
可能有助于创建一个模拟对象,但它不会在您的测试应用程序上下文中产生一个模拟的Spring bean 。用于@SpyBean
在 Spring 应用程序上下文中让 Mockito 监视 bean。
推荐阅读
- php - 如何将 Laravel Ajax 响应数据绑定到路由链接中
- hibernate - 子对象上 CreateCriteria 时的延迟初始化异常
- google-chrome - 困惑:在 Chrome Dev-Tools Lighthouse 中说要阻止网络选项卡未显示为已阻止的请求
- java - Xtext MWE2 工作流在生成器上崩溃
- r - 使用拟合的 2 次多项式模型从 Y 值预测 X 值
- reactjs - 称这个反应 HOC 感觉就像我可以用另一种方式抽象这个请建议
- angular - 选择相同值的角度剑道下拉列表时如何触发事件
- java - JNA/WinAPI。模拟鼠标单击会移动鼠标光标并且不会将其返回到起始位置
- python-3.x - 为什么在while循环和if语句中显示错误
- laravel - 如何在我的 laravel 应用程序(已由 cpanel 部署)中更改 public_path 的名称?