为 Spring 重试 max atttemps 编写 Junit 测试用例
Write Junit test case for Spring Retry max atttemps
我想为 spring 重试编写一个 junit 测试用例,我尝试如下所示,但 junit 没有按预期工作。我正在调用 MaxAttemptRetryService.retry 方法,如果失败,它必须尝试最多 3 次。
在这里,Dao 正在调用 rest 服务,即已关闭,因此它应该尝试最多 3 次。因此 dao.sam 方法必须调用 3 次。
服务Class:
@Service
@EnableRetry
public class MaxAttemptRetryService {
@Retryable(maxAttempts=3)
public String retry(String username) throws Exception {
System.out.println("retry???? am retrying...");
int h = maxAttemptDao.sam();
return "kkkk";
}
}
道class:
@Component
public class MaxAttemptDao {
public int sam() throws Exception{
try{
new RestTemplate()
.getForObject("http://localhost:8080/greeting1/{userName}",
String.class, "");
}catch(Exception e){
throw e;
}
return 0;
}
}
测试class:
@RunWith(SpringRunner.class)
public class HystrixServiceTest {
@InjectMocks
private MaxAttemptRetryService maxAttemptRetryService = new MaxAttemptRetryService();
@Mock
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}
@EnableRetry
和 @Retryable
注释应该由 spring 处理,它应该在运行时在 DAO 之外即时生成代理。代理将添加重试功能。
现在,当您 运行 进行测试时,我根本看不到它运行 spring。您提到您是 运行 Spring 引导,但您没有使用 @SpringBootTest
。另一方面,您也没有指定从 HystrixServiceTest
class 上的 @ContextConfiguration
注释加载 class 的配置
所以我得出结论,您没有正确初始化 spring,因此它无法正确处理 @Retry
注释。
其他我觉得不对的地方:
你应该使用 @MockBean
(如果你在测试中正确启动 spring)这样它就不会只是创建一个 @Mock
(为此你需要一个 mockito runner BTW ) 但会创建一个模拟 spring bean 并将其注册到有效覆盖标准 bean 声明的应用程序上下文中。
我认为你应该这样做:
@RunWith(SpringRunner.class)
@SpringBootTest
public class HystrixServiceTest {
@Autowired // if everything worked right, you should get a proxy here actually (you can check that in debugger)
private MaxAttemptRetryService maxAttemptRetryService;
@MockBean
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}
要补充上面的答案:或者为了更快地加载上下文,可以使用以下配置:
@RunWith(SpringJUnit4ClassRunner.class)
@EnableRetry
@ContextConfiguration(classes = { MaxAttemptRetryService.class })
public class HystrixServiceTest {
@Autowired
private MaxAttemptRetryService maxAttemptRetryService;
@MockBean
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}
我想为 spring 重试编写一个 junit 测试用例,我尝试如下所示,但 junit 没有按预期工作。我正在调用 MaxAttemptRetryService.retry 方法,如果失败,它必须尝试最多 3 次。 在这里,Dao 正在调用 rest 服务,即已关闭,因此它应该尝试最多 3 次。因此 dao.sam 方法必须调用 3 次。
服务Class:
@Service
@EnableRetry
public class MaxAttemptRetryService {
@Retryable(maxAttempts=3)
public String retry(String username) throws Exception {
System.out.println("retry???? am retrying...");
int h = maxAttemptDao.sam();
return "kkkk";
}
}
道class:
@Component
public class MaxAttemptDao {
public int sam() throws Exception{
try{
new RestTemplate()
.getForObject("http://localhost:8080/greeting1/{userName}",
String.class, "");
}catch(Exception e){
throw e;
}
return 0;
}
}
测试class:
@RunWith(SpringRunner.class)
public class HystrixServiceTest {
@InjectMocks
private MaxAttemptRetryService maxAttemptRetryService = new MaxAttemptRetryService();
@Mock
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}
@EnableRetry
和 @Retryable
注释应该由 spring 处理,它应该在运行时在 DAO 之外即时生成代理。代理将添加重试功能。
现在,当您 运行 进行测试时,我根本看不到它运行 spring。您提到您是 运行 Spring 引导,但您没有使用 @SpringBootTest
。另一方面,您也没有指定从 HystrixServiceTest
class 上的 @ContextConfiguration
注释加载 class 的配置
所以我得出结论,您没有正确初始化 spring,因此它无法正确处理 @Retry
注释。
其他我觉得不对的地方:
你应该使用 @MockBean
(如果你在测试中正确启动 spring)这样它就不会只是创建一个 @Mock
(为此你需要一个 mockito runner BTW ) 但会创建一个模拟 spring bean 并将其注册到有效覆盖标准 bean 声明的应用程序上下文中。
我认为你应该这样做:
@RunWith(SpringRunner.class)
@SpringBootTest
public class HystrixServiceTest {
@Autowired // if everything worked right, you should get a proxy here actually (you can check that in debugger)
private MaxAttemptRetryService maxAttemptRetryService;
@MockBean
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}
要补充上面的答案:或者为了更快地加载上下文,可以使用以下配置:
@RunWith(SpringJUnit4ClassRunner.class)
@EnableRetry
@ContextConfiguration(classes = { MaxAttemptRetryService.class })
public class HystrixServiceTest {
@Autowired
private MaxAttemptRetryService maxAttemptRetryService;
@MockBean
private MaxAttemptDao maxAttemptDao;
@Test
public void ff() throws Exception{
when(maxAttemptDao.sam()).thenThrow(Exception.class);
maxAttemptRetryService.retry("ll");
verify(maxAttemptDao, times(3)).sam();
}
}