我正在尝试为使用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对象上的测试服务为空。
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运行时有效
我不知道您为什么要尝试测试框架功能,例如重试。通常,您可以假设框架组件已经由框架作者进行了彻底的测试。
忽略这个,我可以看到至少两个问题:
-
deltaHelper
不是模拟,而是您的SUT,但您尝试设置方法调用。如果模拟SUT,则不再测试类,而是测试模拟。如果你想让调用失败,不要模拟调用,而是模拟它的依赖项(例如MyRestService restService
),并让对依赖项的调用抛出异常。 -
您在实际方法调用中传递
ArgumentMatchers.any()
("act")部分),但any()
无条件返回null
(不是某个魔法对象)。如果要对SUT进行操作,则必须传递实际值。any
用于设置mock或验证mock上的调用。为了完整起见,下面是
any()
的源代码:public static <T> T any() { reportMatcher(Any.ANY); return null; }