如何对javanica @HystrixCommand带注释的方法进行单元测试? [英] How can I unit-test javanica @HystrixCommand annotated methods?

查看:279
本文介绍了如何对javanica @HystrixCommand带注释的方法进行单元测试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆