我在我的SpringBoot应用程序“demo”中使用了注释样式的Resilience4j。当通过RestTemplate调用外部后端时,我希望使用TimeLimiter并重试以实现以下目标:
为了查看弹性设置的配置是否如设计的那样工作,我编写了一个IntegrationTest。该测试在概要文件“test”下运行,并使用“application-test.yml”进行配置:
问题:TimeLimiter和Retry被注册,但不执行它们的工作(TimeLimiter不限制呼叫持续时间)。因此,RestTemplate只调用一次,传递空的person
(请参见代码以获得澄清)。链接的示例项目可以被克隆,并在运行测试时展示问题。
application-test.yml
的代码(也在此处:链接到application-test.yml):
resilience4j:
timelimiter:
configs:
default:
timeoutDuration: 5s
cancelRunningFuture: true
instances:
MY_RESILIENCE_KEY:
baseConfig: default
retry:
configs:
default:
maxRetryAttempts: 2
waitDuration: 100ms
retryExceptions:
- java.util.concurrent.TimeoutException
instances:
MY_RESILIENCE_KEY:
baseConfig: default
这个测试的代码(也在这里:integrationTest.java的链接):
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {DemoApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
@ActiveProfiles("test")
public class IntegrationTest {
private TestRestTemplate testRestTemplate;
public final String FANCY_URL = "https://my-fancy-url-doesnt-matter.com/person";
private String apiUrl;
private HttpHeaders headers;
@LocalServerPort
private String localServerPort;
@MockBean
RestTemplate restTemplate;
@Autowired
CallExternalService callExternalService;
@Autowired
SimpleRestEndpointController simpleRestEndpointController;
@Before
public void setup() {
this.headers = new HttpHeaders();
this.testRestTemplate = new TestRestTemplate("username", "password");
this.apiUrl = String.format("http://localhost:%s/person", localServerPort);
}
@Test
public void testShouldRetryOnceWhenTimelimitIsReached() {
// Arrange
Person mockPerson = new Person();
mockPerson.setId(1);
mockPerson.setFirstName("First");
mockPerson.setLastName("Last");
ResponseEntity<Person> mockResponse = new ResponseEntity<>(mockPerson, HttpStatus.OK);
Answer customAnswer = new Answer() {
private int invocationCount = 0;
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
invocationCount++;
if (invocationCount == 1) {
Thread.sleep(6000);
return new ResponseEntity<>(new Person(), HttpStatus.OK);
} else {
return mockResponse;
}
}
};
doAnswer(customAnswer)
.when(restTemplate).exchange(
FANCY_URL,
HttpMethod.GET,
new HttpEntity<>(headers),
new ParameterizedTypeReference<Person>() {});
// Act
ResponseEntity<Person> result = null;
try {
result = this.testRestTemplate.exchange(
apiUrl,
HttpMethod.GET,
new HttpEntity<>(headers),
new ParameterizedTypeReference<Person>() {
});
} catch(Exception ex) {
System.out.println(ex);
}
// Assert
verify(restTemplate, times(2)).exchange(
FANCY_URL,
HttpMethod.GET,
new HttpEntity<>(headers),
new ParameterizedTypeReference<Person>() {});
Assert.assertNotNull(result);
Assert.assertEquals(mockPerson, result.getBody());
}
}
我的应用程序代码显示了这个问题:https://github.com/sidekickjohn/demo
我创建了一个“逻辑”的泳道图,作为readme.md的一部分:https://github.com/sidekickjohn/demo/blob/main/readme.md
如果要模拟由CallExternalService
使用的真正的RESTTemplate
bean,则必须使用Mockito Spy->https://www.baeldung.com/Mockito-Spy
但我通常更喜欢并建议使用WireMock而不是Mockito来模拟HTTPendpoint。
我正在尝试单元测试我的具有@PreAuthorize注释的API。我从智威汤逊得到了认知团体,并将其作为权威。我在api方法的预授权注释中检查了相同的内容。更新:我得到404 No mapping Delete profile/voluc3f5a_test.txt存在 测试类: 控制器方法:
我想在Spring中测试注入依赖关系。 我想要一个这样的测试: 我尝试过使用ContextConfiguration和一个测试配置文件,但是测试失败了,我不想在测试中使用@autowired,我想创建我的类的一个实例,并且bean是自动autowired的。
我想为上面的内容编写单元测试,以测试我正在使用的注释的sampleURL,比如如果我给出任何应该与regex模式匹配的URL。我浏览了以下链接:如何在spring中进行单元测试验证注释,如何使用JUnit测试类的验证注释?但它们没有多大帮助,我也有setSampleURL函数。那么,如何为sampleURL变量编写测试呢。基本上,我想为regex模式编写测试,即我给sampleURL的值是否与re
TestNG有一个很好的特性,可以将注释添加到测试类中(而不是测试方法)。根据文档,当类被注释时,类上所有公共的void返回方法都被视为测试方法。 更新:现在作为一个问题提出。
是否可以通过注释在Spring Cloud Circuit Breaker上使用Resilience4j?我找不到任何关于它的留档,只有关于通过代码使用弹性4j的示例
我是JMH的新手。在运行代码并使用不同的注释之后,我真的不明白它是如何工作的。我使用迭代=1、预热=1、fork=1来查看我的代码将执行一次,但事实并非如此。JMH运行我的代码超过100000次,我不知道为什么。那么,如何控制代码调用的时间?下面是我的代码:(我为测试修复了JMHSample\u 01)