【问题标题】:Integration testing for events in the Jersey container listenerJersey 容器监听器中事件的集成测试
【发布时间】:2020-04-27 23:28:00
【问题描述】:

我有一个基于 Jersey JAX-RS 的应用程序。我需要重构事件处理程序,因此还要为它编写一个测试。

我正在尝试使用 JerseyTest 框架来执行此操作。我创建了一个配置来扩展 ResourceConfig,但是当我使用 target() 调用时,不会调用处理程序。

我将使用代码介绍情况。 这是一个示例资源类:

package com.my.page;

import org.glassfish.hk2.api.messaging.Topic;
import com.my.core.entity.Link;
import com.my.core.location.LinkHitLocationFactory;
import com.my.core.service.LinkService;
import com.my.core.service.link.LinkFinder;
import com.my.core.service.link.LinkFinderFactory;
import com.my.event.LinkHitEvent;
import com.my.exception.FragmentNotFoundException;

import javax.annotation.security.PermitAll;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;

@PermitAll
@Path("/")
public class LinkResource {

    @Inject
    private LinkService linkService;

    @Inject
    private Topic<LinkHitEvent> linkHitPublisher;

    @Inject
    private LinkFinderFactory linkFinderFactory;

    @Inject
    private LinkHitLocationFactory linkHitLocationFactory;


    @GET
    @Path("/{fragment:[^ ]{1,32}}")
    public Response redirect(
            @PathParam("fragment") String fragment,
            @HeaderParam("Range") String range,
            @HeaderParam("User-Agent") String userAgent,
            @Context HttpHeaders headers) throws Exception {

        LinkFinder linkFinder = linkFinderFactory.getLinkFinder(fragment);
        Link link = linkFinder.getLink(fragment);

        if (link.isExpired()) {
            throw new FragmentNotFoundException(fragment);
        }

        linkService.insertHit();
        linkHitPublisher.publish(new LinkHitEvent(link));

        return handlerFactory.getHandler(link).handleGet(link, range).build();
    }
}

事件测试:

package com.my.page;

import org.glassfish.hk2.extras.events.internal.TopicDistributionModule;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import pl.comvision.hk2.events.ThreadedEventDistributorService;
import com.my.client.CallbackTargetBuilder;
import com.my.core.entity.Link;
import com.my.core.mapper.LinkMapper;
import com.my.core.service.LinkService;
import com.my.page.resource.LinkResource;

import javax.ws.rs.core.Application;
import javax.ws.rs.core.Response;

import static javax.ws.rs.core.Response.Status.TEMPORARY_REDIRECT;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class CallbackEventTest extends JerseyTest {
    @Mock
    private LinkMapper linkMapper;

    @Mock
    private LinkService linkService;

    private CallbackTargetBuilder callbackTargetBuilder;
    private final String callbackUrl = "";

    @Override
    protected Application configure() {
        this.callbackTargetBuilder = spy(new CallbackTargetBuilder(this.callbackUrl));

        ResourceConfig config = new ResourceConfig(LinkResource.class);
        config.register(new TopicDistributionModule());
        config.register(new AbstractBinder() {
            @Override
            protected void configure() {
                addActiveDescriptor(ThreadedEventDistributorService.class).setRanking(100);
            }
        });
        config.register(new EventsContainerListener(CallbackEventHandler.class));

        config.register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(linkMapper).to(LinkMapper.class);
                bind(linkService).to(LinkService.class);
                bind(mock(LinkService.class)).to(LinkService.class);

                bind("").to(String.class).named("varPath");
                bind("127.0.0.1").to(String.class).named("requestIP");
                bind(callbackTargetBuilder).to(CallbackTargetBuilder.class);
            }
        });

        return config;
    }

    @Test
    public void publish_event() {
        Link link = mock(Link.class);
        when(link.getUrl()).thenReturn("example");
        when(link.getName()).thenReturn("test");
        when(linkMapper.getByName(anyString())).thenReturn(link);

        Response response = target("/testY").property("jersey.config.client.followRedirects", false).request().get();
        assertEquals(TEMPORARY_REDIRECT.getStatusCode(), response.getStatus());
        verify(callbackTargetBuilder).build();
    }
}

出于测试目的,我只将 callbackTargetBuilder 注入到 handler 中,并在其上调用 build 方法来验证调用:

package com.my.page;

import org.glassfish.hk2.api.messaging.MessageReceiver;
import org.glassfish.hk2.api.messaging.SubscribeTo;
import org.jvnet.hk2.annotations.Service;
import com.my.client.CallbackTargetBuilder;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Form;
import javax.ws.rs.core.MediaType;

@Service
@Singleton
@MessageReceiver
public class CallbackEventHandler {

    @Named("callbackUrl")
    private String url;

    @Inject
    private CallbackTargetBuilder callbackTargetBuilder;

    @MessageReceiver
    public void handle(@SubscribeTo LinkHitEvent event) {
        Form form = new Form();
        form.param("id", event.getLink().getId().toString());
        form.param("name", event.getLink().getName());

        callbackTargetBuilder.build();

        Client client = ClientBuilder.newClient();
        client.target(url).request().post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE));
    }
}

编辑: 我尝试以不同的方式注册依赖项,但并没有带来令人满意的结果。每次验证失败: verify (callbackTargetBuilder) .build ();

找资料发现可以配置DeploymentContext,但不知道这个方向对不对。

编辑第二个: 快速测试表明我可能在模拟方面遇到了一些更基本的问题。因为调用: verify (linkService) .insertHit (anyObject ()); 它也失败了。

【问题讨论】:

    标签: java testing jersey jax-rs


    【解决方案1】:

    我将只为后人编写上述代码是正确的。问题是测试代码中有很多小错误以及如何模拟它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-17
      • 2019-12-31
      • 2014-11-16
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多