英文:
Mock constructor value in JUnit test
问题
我有以下控制器需要测试:
@RestController
@RequestMapping("/api/account")
public class AccountController {
private final AccountService accountService;
private UUID correspondentId;
public AccountController(AccountService accountService, @Value("${app.correspondent}") String correspondentId) {
this.accountService = accountService;
this.correspondentId = UUID.fromString(correspondentId);
}
@GetMapping("")
@PreAuthorize("hasRole('CUSTOMER')")
Mono<String> index(Authentication auth) {
return ...;
}
}
我尝试模拟测试如下:
@Test
public void testMockUser() {
AccountService accountService = Mockito.mock(AccountService.class);
Mockito.mock(AccountController.class, withSettings().useConstructor(accountService,
UUID.randomUUID());
webTestClient
.mutateWith(jwtMutator())
.get().uri("/api/account/")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk();
}
但是我收到了错误信息:
Caused by: java.lang.IllegalArgumentException: Invalid UUID string:
您知道正确模拟构造函数值的方法吗?
英文:
I have the following controller which I want to test:
@RestController
@RequestMapping("/api/account")
public class AccountController {
private final AccountService accountService;
private UUID correspondentId;
public AccountController(AccountService accountService, @Value("${app.correspondent}") String correspondentId) {
this.accountService = accountService;
this.correspondentId = UUID.fromString(correspondentId);
}
@GetMapping("")
@PreAuthorize("hasRole('CUSTOMER')")
Mono<String> index(Authentication auth) {
return.....;
}
I tried to mock a test this way:
@Test
public void testMockUser() {
AccountService accountService = Mockito.mock(AccountService.class);
Mockito.mock(AccountController.class, withSettings().useConstructor(accountService,
UUID.randomUUID()));
webTestClient
.mutateWith(jwtMutator())
.get().uri("/api/account/")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk();
}
But I get error:
Caused by: java.lang.IllegalArgumentException: Invalid UUID string:
Do you know what is the proper way to mock the constructor value?
答案1
得分: 1
我认为问题可能与创建bean本身有关,而不是模拟对象(可能它在测试环境中将@Value("${app.correspondent}")
解析为""
,然后因为它不是UUID而失败)。我建议在属性中放入类似app.correspondent=d7aa282f-a8aa-40f9-bce6-08ce6737b6e1
的内容,然后进行检查。
此外,看起来还有另一个可能遇到的问题:控制器中的方法签名是AccountService, String
,而模拟中是AccountService, UUID
。几乎可以确定这会导致模拟对象构造时出现错误。不过,这可以通过简单的toString方法进行修复。
英文:
I think the problem might be related to creating the bean itself and not the mock (probably it resolves @Value("${app.correspondent}")
to ""
in the test environment and then fails as it's not an UUID. I suggest putting something like app.correspondent=d7aa282f-a8aa-40f9-bce6-08ce6737b6e1
in the properties and check it out.
Also, it looks like there's another problem you might face: it's AccountService, String
method signature in the controller and AccountService, UUID
in the mock. Pretty sure this will give another error with mock construction. Though, this is easy to fix with a simple toString.
答案2
得分: 0
一旦你使用Spring,然后在 application-test.properties
文件中,你可以添加
app.correspondent=some-value
在测试类中,你可以使用 @MockBean
注解,如下所示:
class TestClass {
@MockBean
private AccountService accountService;
}
在Spring启动时,Spring将使用从 application-test.properties
文件中注入的值创建 AccountController
,并使用模拟的 accountService
。
英文:
As soon as you use Spring then in application-test.properties
you could add
app.correspondent=some-value
And in test class you use @MockBean
as:
class TestClass {
@MockBean
private AccountService accountService;
}
At context start-up Spring will create AccountController
with the value injected from application-test.properties
and mocked accountService
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论