Sha*_*Sha 1 unit-testing mockito spring-boot
我有一个如下代码块:
@Service
ExecutorService {
@Autowired
IAccountService accountService;
@Retryable(maxAttempts = 3, value = {DataIntegrityViolationException.class}, backoff = @Backoff(delay = 1000, multiplier = 2))
public void execute(RequestDto reqDto)
{
Account acc = accountService.getAccount(reqDto.getAccountId);
...
}
}
Run Code Online (Sandbox Code Playgroud)
在 Mockito 测试中,我只想按预期看到调用方法 3 次。
@RunWith(SpringRunner.class)
public class CampaignExecuterServiceTest
{
private static final Long ACCOUNT_ID = 1L;
@InjectMocks
private ExecutorService executorService;
@Mock
private IAccountService accountService;
@Test
public void execute_success()
{
Account account = new Account(ACCOUNT_ID, null, null, null, null);
RequestDto reqDto = new RequestDto();
when(accountService.getAccount(any())).thenThrow(DataIntegrityViolationException.class);
executorService.execute(reqDto);
verify(executorService, times(3)).execute(any());
}
}
Run Code Online (Sandbox Code Playgroud)
测试只是抛出异常。但我预计它会调用 3 次。
这里有一些问题。
1)@SpringBootTest需要创建一个 Spring Boot 应用程序运行器来拦截您的可重试方法。JUnit 本身不会这样做。此外,classes参数必须是您的主类,而不是MainApplication可以作为 Spring boot 应用程序运行的类的子集。
2)ExecutorService必须带有注释,@Autowired因此它将是测试正在创建的 Spring boot 应用程序中的 bean。
3)IAccountService必须是一个@MockBean,这就是测试 Spring boot 环境如何知道使用模拟类ExecutorService而不是真正的 bean。
4)在测试中,第三个模拟调用需要返回有效结果,否则会抛出异常,测试将失败。或者,您可以在测试中捕获异常。
5)ExecutorService不是模拟或间谍,因此verify在运行时不会接受它作为参数,但它accountService是模拟,所以只需断言它被调用 3 次。
另一个注意事项是,在 Spring boot 配置或上的某个位置,MainApplication您必须有@EnableRetry注释。
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MainApplication.class)
public class CampaignExecuterServiceTest {
private static final Long ACCOUNT_ID = 1L;
@Autowired
private ExecutorService executorService;
@MockBean
private IAccountService accountService;
@Test
public void execute_success() {
Account account = new Account(ACCOUNT_ID, null, null, null, null);;
RequestDto reqDto = new RequestDto();
when(accountService.getAccount(any()))
.thenThrow(DataIntegrityViolationException.class)
.thenThrow(DataIntegrityViolationException.class)
.thenReturn(account);
executorService.execute(reqDto);
verify(accountService, times(3)).getAccount(any());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10477 次 |
| 最近记录: |