我有这个测试:
@RunWith(MockitoJUnitRunner.class)
public class myServiceTest {
@InjectMocks
myService subject;
private myService spy;
@Before
public void before() {
spy = spy(subject);
}
@Test
public void testing() {
when(spy.print2()).thenThrow(new RuntimeException()).thenThrow(new RuntimeException()).thenReturn("completed");
spy.print1();
verify(spy, times(3)).print2();
}
然后我有:
@Service("myService")
public class myService extends myAbstractServiceClass {
public String print1() {
String temp = "";
temp = print2();
return temp;
}
@Retryable
public String print2() {
return "completed";
}
}
然后我有这个接口(我的abstractService实现):
public interface myServiceInterface {
@Retryable(maxAttempts = 3)
String print1() throws RuntimeException;
@Retryable(maxAttempts = 3)
String print2() throws RuntimeException;
}
但是,当我运行测试时,我得到了一个runtimeexception,这让我相信它没有重试。我做错了吗?
4条答案
按热度按时间ahy6op9u1#
这是因为您没有使用
SpringJUnitClassRunner
。Mockito和您自己的类没有考虑
@Retryable
注解。所以你依赖Spring的实现来做到这一点。但是你的测试并没有激活Spring。SpringJUnit4ClassRunner JavaDoc:
SpringJUnit 4ClassRunner是JUnit的BlockJUnit 4ClassRunner的自定义扩展,它通过TestContextManager和相关的支持类和注解为标准JUnit测试提供Spring TestContext框架的功能。要使用此类,只需使用@RunWith(SpringJUnit4ClassRunner.class)或@RunWith(SpringRunner.class)注解基于JUnit 4的测试类。
你应该重新构造你的测试类,至少像这样:
我在那里干什么?
1.激活Spring JUnit钩子
1.指定Spring上下文配置类
1.定义spring配置并将服务作为bean导入
1.启用可重试注解
还有其他的陷阱吗?
test -> retryableService -> exceptionThrowingBean
.然后你可以使用Springockito或任何你喜欢的,例如。ReflectionTestUtils
配置exceptionThrowingBean
您喜欢的行为。MyServiceInterface
first letter of each internal word capitalized
希望能帮上忙。
bxgwgixi2#
另一种方式:
ghg1uchk3#
我认为应该让Spring管理bean,创建适当的代理并处理过程。如果要模拟特定的bean,可以创建模拟并将其注入到测试服务中。
第一个选项可能是解包代理服务,创建模拟并手动注入它们:
在本例中,我模拟了一个bean RetryProperties,并注入到服务中。还要注意,在这种方法中,您正在修改Spring缓存的测试应用程序上下文。这意味着,如果你不使用@DirtiesContext,service将在其他测试中继续使用mocked bean。您可以在这里阅读更多
第二种选择是创建一个特定于测试的@Configuration,并在那里模拟依赖的bean。Spring将选择这个新的mocked bean,而不是原来的bean:
在本例中,我们定义了一个测试特定的配置,并将其添加到@ContextConfiguration中。
gpfsuwkq4#
这个解决方案对我很有效:
Gradle:
主要类别:
包含@ blog的类:
测试: