为 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();
  }


}