我尝试用springRunner为一个类写单元测试,但是我的@Autowired bean是空的,你能告诉我我做错了什么吗?
下面是我的测试类
@RunWith(SpringRunner.class)
@ContextConfiguration
public class DeltaHelperTest {
@Autowired
private DeltaHelper deltaHelper;
@Before
public void setUp() { System.setProperty("delta.process.retries", "2"); }
@After
public void validate() { validateMockitoUsage(); }
@Test
public void retriesAfterOneFailAndThenPass() throws Exception {
when(deltaHelper.restService.call(any(), any())).thenThrow(new HttpException());
deltaHelper.process(any(),any());
verify(deltaHelper, times(2)).process(any(), any());
}
@Configuration
@EnableRetry
@EnableAspectJAutoProxy(proxyTargetClass=true)
@Import(MockitoSkipAutowireConfiguration.class)
public static class Application {
@Bean
public DeltaHelper deltaHelper() {
DeltaHelper deltaHelper = new DeltaHelper();
deltaHelper.myStorageService= myStorageService();
deltaHelper.restService = restService();
return deltaHelper;
}
@Bean
public MyStorageService myStorageService() {
return new MyStorageService();
}
@Bean
public MyRestService restService() {
return new MyRestService();
}
@Bean
public MyRepo myRepository() {
return mock(MyRepo.class);
}
}
@Configuration
public static class MockitoSkipAutowireConfiguration {
@Bean MockBeanFactory mockBeanFactory() {
return new MockBeanFactory();
}
private static class MockBeanFactory extends InstantiationAwareBeanPostProcessorAdapter {
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return !mockingDetails(bean).isMock();
}
}
}
}
此处测试服务在deltaHelper对象上为null。
MyRepo.class被嘲笑,因为它有一些更多的@autowired bean引用
在此处附加其他类
@Component
public class DeltaHelper {
@Autowired
MyRestService restService;
@Autowired
MyStorageService myStorageService;
@NotNull
@Retryable(
value = Exception.class,
maxAttemptsExpression = "${delta.process.retries}"
)
public String process(String api, HttpEntity<?> entity) {
return restService.call(api, entity);
}
@Recover
public String recover(Exception e, String api, HttpEntity<?> entity) {
myStorageService.save(api);
return "recover";
}
}
@Service
public class MyStorageService {
@Autowired
MyRepo myRepo;
@Async
public MyEntity save(String api) {
return myRepo.save(new MyEntity(api, System.currentTimeMillis()));
}
}
public class MyRestService extends org.springframework.web.client.RestTemplate {
}
谢谢
尝试使用MockitoJUnitRunner,但发现@Retryable仅在使用Spring运行时有效
1条答案
按热度按时间zynd9foi1#
我不知道你为什么要测试框架功能,比如retry,一般来说,你可以假设框架组件已经被框架作者彻底测试过了。
忽略这一点,我至少可以看到两个问题:
deltaHelper
不是模拟,而是您的SUT,但您尝试设置方法调用。如果您模拟SUT,则不再测试您的类,而是测试模拟。如果您希望调用失败,请不要模拟调用,而是模拟其依赖项(例如MyRestService restService
),并让对依赖项的调用抛出异常。1.在真实的方法调用(“act”部分)中传递
ArgumentMatchers.any()
,但是any()
无条件返回null
(不是某个魔术对象)。如果要对SUT进行操作,必须传递实值。any
用于设置模拟或验证对模拟的调用。为了完整起见,下面是
any()
的源代码: