Spring-重试表达式在 Junit4 中失败
Spring-retry expression failing in Junit4
该服务与正常的 spring 启动应用完美配合。但是在 运行 junit 时出现异常。以下是我的异常详细信息...
org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from java.lang.String to java.lang.Integer
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:75)
at org.springframework.expression.common.ExpressionUtils.convertTypedValue(ExpressionUtils.java:57)
at org.springframework.expression.common.LiteralExpression.getValue(LiteralExpression.java:92)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.getRetryPolicy(AnnotationAwareRetryOperationsInterceptor.java:303)
...
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
...
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at
...
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value '${max.read.attempts}'; nested exception is java.lang.NumberFormatException: For input string: "${max.read.attempts}"
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:46)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:70)
... 41 more
Caused by: java.lang.NumberFormatException: For input string: "${max.read.attempts}"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:569)
at java.lang.Integer.valueOf(Integer.java:766)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:210)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:62)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:49)
at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
... 43 more
在我的服务中,我有如下所示的可重试标签。此服务已注入 Spring-boot rest apis。但是我想单独测试这个服务。
@Retryable(maxAttemptsExpression = "${max.read.attempts}", value = { IOException.class }, backoff = @backoff(delayExpression = "${retry.delay}"))
我的测试用例如下。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ConfigInvokeServiceTest {
@Autowired
@Qualifier("configService")
ConfigInvokeService configInvokeService;
@Test
public void invoke() throws ClientProtocolException, IOException {
String message = configInvokeService.invoke();
verify(configInvokeService, times(3)).invoke();
assertThat(message, is("Completed"));
}
@Configuration
@EnableRetry
public static class SpringConfig {
@Bean(name = "configService")
public ConfigInvokeService configInvokeService() throws Exception {
ConfigInvokeService remoteService = mock(ConfigInvokeService.class);
when(remoteService.invoke())
.thenThrow(new RuntimeException("Remote Exception 1"))
.thenThrow(new RuntimeException("Remote Exception 2"))
.thenReturn("Completed");
return remoteService;
}
}
}
如果它是 Spring 引导应用程序,请使用 @SpringBootTest
以便将引导属性加载到您的测试用例中。
否则,您需要将 PropertyPlaceHolderConfigurer
@Bean
添加到 SpringConfig
以及指向属性文件的指针。
该服务与正常的 spring 启动应用完美配合。但是在 运行 junit 时出现异常。以下是我的异常详细信息...
org.springframework.expression.spel.SpelEvaluationException: EL1001E: Type conversion problem, cannot convert from java.lang.String to java.lang.Integer
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:75)
at org.springframework.expression.common.ExpressionUtils.convertTypedValue(ExpressionUtils.java:57)
at org.springframework.expression.common.LiteralExpression.getValue(LiteralExpression.java:92)
at org.springframework.retry.annotation.AnnotationAwareRetryOperationsInterceptor.getRetryPolicy(AnnotationAwareRetryOperationsInterceptor.java:303)
...
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
...
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at
...
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Integer] for value '${max.read.attempts}'; nested exception is java.lang.NumberFormatException: For input string: "${max.read.attempts}"
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:46)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
at org.springframework.expression.spel.support.StandardTypeConverter.convertValue(StandardTypeConverter.java:70)
... 41 more
Caused by: java.lang.NumberFormatException: For input string: "${max.read.attempts}"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:569)
at java.lang.Integer.valueOf(Integer.java:766)
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:210)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:62)
at org.springframework.core.convert.support.StringToNumberConverterFactory$StringToNumber.convert(StringToNumberConverterFactory.java:49)
at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:40)
... 43 more
在我的服务中,我有如下所示的可重试标签。此服务已注入 Spring-boot rest apis。但是我想单独测试这个服务。
@Retryable(maxAttemptsExpression = "${max.read.attempts}", value = { IOException.class }, backoff = @backoff(delayExpression = "${retry.delay}"))
我的测试用例如下。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ConfigInvokeServiceTest {
@Autowired
@Qualifier("configService")
ConfigInvokeService configInvokeService;
@Test
public void invoke() throws ClientProtocolException, IOException {
String message = configInvokeService.invoke();
verify(configInvokeService, times(3)).invoke();
assertThat(message, is("Completed"));
}
@Configuration
@EnableRetry
public static class SpringConfig {
@Bean(name = "configService")
public ConfigInvokeService configInvokeService() throws Exception {
ConfigInvokeService remoteService = mock(ConfigInvokeService.class);
when(remoteService.invoke())
.thenThrow(new RuntimeException("Remote Exception 1"))
.thenThrow(new RuntimeException("Remote Exception 2"))
.thenReturn("Completed");
return remoteService;
}
}
}
如果它是 Spring 引导应用程序,请使用 @SpringBootTest
以便将引导属性加载到您的测试用例中。
否则,您需要将 PropertyPlaceHolderConfigurer
@Bean
添加到 SpringConfig
以及指向属性文件的指针。