2015-04-07 2 views
4

Я работаю над реализацией API REST с использованием Jersey. Для PATCH (частичные обновления) я внедрил собственную собственную реализацию PATCH, так как Джерси ее не поддерживает.Использование PATCH с API-интерфейсом Джерси для модульного тестирования

Теперь я пытаюсь понять, как писать функциональные тесты вокруг этой реализации. Я использую каркас трикотажа для других методов (PUT, POST, GET, DELETE), который имеет эту поддержку в этой структуре.

Есть ли способ, в котором я могу расширить реализацию каркаса трикотажа, чтобы написать свои функциональные тесты для PATCH? Если нет, существуют ли какие-либо другие тестовые рамки, которые я могу использовать для тестирования моей версии Jersey PATCH?

Если кто-нибудь может предоставить какие-либо примеры, это было бы здорово.

ответ

0

Предполагая, что ваша реализация состоит из аннотаций, как этот

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import javax.ws.rs.HttpMethod; 

@HttpMethod("PATCH") 
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface PATCH {} 

Попытка сделать что-то подобное с Client

String response = target.request().method("PATCH", Entity.text("Hello"), String.class); 

по умолчанию не поддерживается, и будет исключение, как

java.net.ProtocolException: Invalid HTTP method: PATCH 

Это не представляет проблемы с Client API напрямую, но с Java-интерфейсами более низкого уровня. Кажется, это ограничение безопасности.

С Client API можно переопределить, задав свойство

В JerseyTest, один из способов настроить Client это переопределить configureClient и установить свойство с ClientConfig. Вы можете так же легко установить свойство на самом Client, но оставаясь в духе JerseyTest рамок (где мы не должны явно получить доступ к Client, в приведенном ниже примере будет только просто переопределить метод

public class PatchTest extends JerseyTest { 

    @Path("patch") 
    public static class PatchResource { 
     @PATCH 
     @Produces(MediaType.TEXT_PLAIN) 
     public String getPatch(String request) { 
      return "Patched " + request; 
     } 
    } 

    @Override 
    protected void configureClient(final ClientConfig config) { 
     config.property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true); 
    } 

    @Override 
    public Application configure() { 
     return new ResourceConfig(PatchResource.class); 
    } 

    @Test 
    public void doPatchTest() { 
     WebTarget target = target("patch"); 
     String response = target.request().method("PATCH", Entity.text("Hello"), String.class); 
     Assert.assertEquals("Patched Hello", response); 
     System.out.println(response); 
    } 
} 
3

Чтобы отправить HTTP PATCH через JAX RS Client API без какой-либо дополнительной конфигурации:.

client.target("$baseUrl$restUsersUrl/$userId") 
       .request("application/json") 
       .build("PATCH", Entity.entity(json2Update, MediaType.APPLICATION_JSON)) 
       .invoke() 
1

Аннотация @PATCH теперь доступна в JAX-RS 2.1 Вы можете реализовать этот метод HTTP на стороне сервера, как:

@PATCH 
public Response updateResource() { ... } 

Что касается стороны клиента, вы можете сделать что-то вроде:

Response r = ClientBuilder.newClient() 
    .target("http://localhost:8080/patch") 
    .request() 
    .build("PATCH", Entity.text("patch")) 
    .property(HttpUrlConnectorProvider.SET_METHOD_WORKAROUND, true) 
    .invoke(); 

Где SET_METHOD_WORKAROUND используется, чтобы избежать исключения протокола, как указано @peeskillet:

java.net.ProtocolException: Invalid HTTP method: PATCH 
Смежные вопросы