如何对javanica @HystrixCommand带注释的方法进行单元测试? [英] How can I unit-test javanica @HystrixCommand annotated methods?
问题描述
我正在使用javanica并注释我的hystrix命令方法,如下所示:
I am using javanica and annotating my hystrix command methods like this:
@HystrixCommand(groupKey="MY_GROUP", commandKey="MY_COMMAND" fallbackMethod="fallbackMethod")
public Object getSomething(Object request) {
....
并且我正在尝试对我的后备方法进行单元测试,而不必直接调用它们,即,我想调用@HystrixCommand
注释的方法,并在抛出500错误后让它自然地流入后备方法.所有这些都可以在单元测试之外进行.
And I am trying to unit tests my fallback methods, without having to call them directly, i.e. I would like to call the @HystrixCommand
annotated method and let it flow naturally into the fallback after throwing a 500 error. This all works outside of unit tests.
在单元测试中,我正在使用弹簧MockRestServiceServer
返回500个错误,该部分正在工作,但是Hystrix在单元测试中未正确初始化.在我的测试方法开始时,我有:
In my unit tests I am using springs MockRestServiceServer
to return 500 errors, this part is working, but Hystrix is not being initialized correctly on my unit tests. At the beginning of my test method I have:
HystrixRequestContext context = HystrixRequestContext.initializeContext();
myService.myHystrixCommandAnnotatedMethod();
此后,我尝试通过键获取任何hystrix命令,并检查是否有任何已执行的命令,但列表始终为空,我正在使用此方法:
After this I am trying to get any hystrix command by key and checking if there are any executed commands but the list is always empty, I am using this method:
public static HystrixInvokableInfo<?> getHystrixCommandByKey(String key) {
HystrixInvokableInfo<?> hystrixCommand = null;
System.out.println("Current request is " + HystrixRequestLog.getCurrentRequest());
Collection<HystrixInvokableInfo<?>> executedCommands = HystrixRequestLog.getCurrentRequest()
.getAllExecutedCommands();
for (HystrixInvokableInfo<?> command : executedCommands) {
System.out.println("executed command is " + command.getCommandGroup().name());
if (command.getCommandKey().name().equals(key)) {
hystrixCommand = command;
break;
}
}
return hystrixCommand;
}
我意识到我在单元测试初始化中丢失了一些东西,有人可以向我指出如何正确进行单元测试的正确方向吗?
I realize I am missing something in my unit tests initialization, can anyone point me in the right direction on how I can properly unit-test this?
推荐答案
尽管您不一定必须UNIT测试hystrix命令.进行某种春季混合测试仍然很有用,我认为在添加注释时点空白接受功能是不正确的.我创建的测试可确保断路器在出现异常时断开.
Although you shouldn't necessarily UNIT test hystrix command. It's still useful to have a sort of spring hybrid test, I think point blank accepting the functionality when adding the annotation isn't correct. The test I created ensures that the circuit breaker opens on an exception.
@RunWith(SpringRunner.class)
@SpringBootTest
public class HystrixProxyServiceTests {
@MockBean
private MyRepo myRepo;
@Autowired
private MyService myService;
private static final String ID = "1";
@Before
public void setup() {
resetHystrix();
openCircuitBreakerAfterOneFailingRequest();
}
@Test
public void circuitBreakerClosedOnSuccess() throws IOException, InterruptedException {
when(myRepo.findOneById(USER_ID1))
.thenReturn(Optional.of(Document.builder().build()));
myService.findOneById(USER_ID1);
HystrixCircuitBreaker circuitBreaker = getCircuitBreaker();
Assert.assertTrue(circuitBreaker.allowRequest());
verify(myRepo, times(1)).findOneById(
any(String.class));
}
@Test
public void circuitBreakerOpenOnException() throws IOException, InterruptedException {
when(myRepo.findOneById(ID))
.thenThrow(new RuntimeException());
try {
myService.findOneById(ID);
} catch (RuntimeException exception) {
waitUntilCircuitBreakerOpens();
HystrixCircuitBreaker circuitBreaker = getCircuitBreaker();
Assert.assertFalse(circuitBreaker.allowRequest());
}
verify(myRepo, times(1)).findOneById(
any(String.class));
}
private void waitUntilCircuitBreakerOpens() throws InterruptedException {
Thread.sleep(1000);
}
private void resetHystrix() {
Hystrix.reset();
}
private void warmUpCircuitBreaker() {
myService.findOneById(USER_ID1);
}
public static HystrixCircuitBreaker getCircuitBreaker() {
return HystrixCircuitBreaker.Factory.getInstance(getCommandKey());
}
private static HystrixCommandKey getCommandKey() {
return HystrixCommandKey.Factory.asKey("findOneById");
}
private void openCircuitBreakerAfterOneFailingRequest() {
ConfigurationManager.getConfigInstance().
setProperty("hystrix.command.findOneById.circuitBreaker.requestVolumeThreshold", 1);
}
}
让我绊了一会儿的另一件事是,我输入的默认注释没有特定的命令键,但是创建命令键时,它们是根据我上面指定的方法名称创建的.对于一个完整的示例,我还添加了注释以显示我未指定commandKey.
Another little thing that tripped me up for a while was that I had entered the default annotations without a specific command key, however when the command keys are created they are created against the method name which is what I've specified above. For a complete example I've also added the annotation to show I didn't specify a commandKey.
@HystrixCommand
public Optional<Document> findOneById(final String id) {
return this.myRepo.findOneById(id);
}
希望这对某人有帮助.
这篇关于如何对javanica @HystrixCommand带注释的方法进行单元测试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!