У меня есть приложение, основанное на Джерси JAX-RS. Мне нужно провести рефакторинг обработчика событий и, следовательно, также написать для него тест.
Я пытаюсь сделать это с помощью JerseyTest Framework. Я создал конфигурацию для расширения 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 в обработчик и вызвал метод сборки для его проверки call:
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, но не знаю, верное ли это направление.
Редактировать второе: A быстрый тест показывает, что у меня может быть еще одна базовая c проблема с насмешкой. Потому что звонок: verify (linkService) .insertHit (anyObject ());
тоже не получается.