Como usar mockito para testar um serviço de descanso?

sou muito novo em Java Unit Testing e ouvi dizer que o Mockito framework é muito bom para testes.

Desenvolvi um servidor de descanso( métodos CRUD) e agora quero testá-lo, mas não sei como?

Ainda mais não sei como este procedimento de teste deve começar. Meu servidor deve trabalhar em localhost e, em seguida, fazer chamadas sobre esse url(por exemplo, localhost:8888)?

Eis o que tentei até agora, mas tenho a certeza que não é o certo. forma.

    @Test
    public void testInitialize() {
        RESTfulGeneric rest = mock(RESTfulGeneric.class);

        ResponseBuilder builder = Response.status(Response.Status.OK);

        builder = Response.status(Response.Status.OK).entity(
                "Your schema was succesfully created!");

        when(rest.initialize(DatabaseSchema)).thenReturn(builder.build());

        String result = rest.initialize(DatabaseSchema).getEntity().toString();

        System.out.println("Here: " + result);

        assertEquals("Your schema was succesfully created!", result);

    }

Aqui está o código para o método initialize.

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/initialize")
    public Response initialize(String DatabaseSchema) {

        /** Set the LogLevel to Info, severe, warning and info will be written */
        LOGGER.setLevel(Level.INFO);

        ResponseBuilder builder = Response.status(Response.Status.OK);

        LOGGER.info("POST/initialize - Initialize the " + user.getUserEmail()
                + " namespace with a database schema.");

        /** Get a handle on the datastore itself */
        DatastoreService datastore = DatastoreServiceFactory
                .getDatastoreService();


        datastore.put(dbSchema);

        builder = Response.status(Response.Status.OK).entity(
                "Your schema was succesfully created!");
        /** Send response */
        return builder.build();
    }

neste caso de teste quero enviar um texto Json para o servidor(POST). Se tudo correu bem, então o servidor deve responder com " seu esquema foi succesfully criado!".

Alguém me pode ajudar?

Author: Ion Morozan, 2012-05-27

5 answers

Está bem. Então, o Contrato do método é o seguinte: Analisar a cadeia de entrada como JSON, e enviar de volta BAD_REQUEST Se for inválido. Se for válido, crie uma entidade no datastore com várias propriedades( Você As conhece), e envie de volta OK.

E você precisa verificar se este contrato é cumprido pelo método.

Onde é que o Mockito ajuda aqui? Bem, se você testar este método sem Mockito, você precisa de um real {[[5]}, e você precisa verificar que a entidade foi criada corretamente neste real DataStoreService. Aqui é onde seu teste não é mais um teste de unidade, e aqui também é onde ele é muito complexo para testar, muito longo, e muito difícil de executar porque ele precisa de um ambiente complexo.

Mockito pode ajudar zombando da dependência do DataStoreService: você pode criar um mock de DataStoreService, e verificar que este mock é realmente chamado com o argumento de entidade apropriada quando você chama o seu método initialize() no seu teste.

Para fazer isso, tem de ser capaz de injectar o DataStoreService em o teu objecto está a ser testado. Pode ser tão fácil como refactorar o seu objecto da seguinte forma:

public class MyRestService {
    private DataStoreService dataStoreService;

    // constructor used on the server
    public MyRestService() {
        this.dataStoreService = DatastoreServiceFactory.getDatastoreService();
    }

    // constructor used by the unit tests
    public MyRestService(DataStoreService dataStoreService) {
        this.dataStoreService = dataStoreService;
    }

    public Response initialize(String DatabaseSchema) {
         ...
         // use this.dataStoreService instead of datastore
    }
}

E agora no seu método de teste, pode fazer:

@Test
public void testInitializeWithGoodInput() {
    DataStoreService mockDataStoreService = mock(DataStoreService.class);
    MyRestService service = new MyRestService(mockDataStoreService);
    String goodInput = "...";
    Response response = service.initialize(goodInput);
    assertEquals(Response.Status.OK, response.getStatus());

    ArgumentCaptor<Entity> argument = ArgumentCaptor.forClass(Entity.class);
    verify(mock).put(argument.capture());
    assertEquals("the correct kind", argument.getValue().getKind());
    // ... other assertions
}
 21
Author: JB Nizet, 2018-01-12 20:37:49

O que você está falando soa mais comoteste de Integração e Mockito (ou qualquer outro frameworks zombando) não será de grande utilidade para você.

Se você quer o código de teste de unidade que você escreveu, Mockito é certamente uma ferramenta útil.

Sugiro que leia mais sobre zombar/testar a unidade e em que circunstâncias deve ser utilizado.
 3
Author: darrengorman, 2012-05-27 15:58:08

Mockito é (geralmente) para testar porções de código; por exemplo, se você estava consumindo o seu serviço de repouso, mas não queria fazer um teste de pilha completa, você iria zombar do serviço que conectou ao serviço de repouso, permitindo-lhe precisamente, e consistentemente, testar o comportamento específico.

Para testar partes internas do serviço de repouso (por exemplo, um método de serviço específico) sem atingir uma base de dados, você zombaria do subsistema DB, permitindo testar apenas os internos do serviço, sem envolvendo o cadáver. Este teste pertence ao módulo de serviço de descanso, não ao lado do cliente.

Para testar o serviço de descanso em si, você usaria uma biblioteca de clientes real, criando um teste de integração de pilha completa. Mockito poderia ser usado aqui para zombar de partes do cliente não relacionadas com o consumo de serviço de repouso.

 2
Author: Dave Newton, 2012-05-27 16:03:44

O melhor método é usar o wiremock adicionar as seguintes dependências com.github.tomakehurst wiremock 2.4.1 org.hora da ignitereal.smack smack-core 4.0.6

Defina e utilize o wiremock como mostrado abaixo

@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);

String response ="Hello world";
StubMapping responseValid = stubFor(get(urlEqualTo(url)).withHeader("Content-Type", equalTo("application/json"))
        .willReturn(aResponse().withStatus(200)
                .withHeader("Content-Type", "application/json").withBody(response)));
 1
Author: Yallaling Goudar, 2016-12-07 13:39:44
Concordo que isto não é um teste de unidade, mas um teste de integração, de qualquer forma, preferes ver os testes de jersey e os testes de servidor grizzly incorporados. Para suavizá-lo, este código inicia o servidor grizzly (que poderia iniciar a base de dados também) em localhost:8888, em seguida, configurar o cliente do cliente jersey e envia um pedido POST que a resposta deve ser testada. Esta é uma integração uma vez que você está testando tanto servidor e banco de dados, você pode usar mockito para emular o banco de dados no entanto, mas depende de quão amarrado o seu servidor e a sua base de dados são.

(teste utilizando jersey 1.11 e grizzly 2.2)

    @BeforeClass
    public static void setUpClass() throws Exception {
        // starts grizzly
        Starter.start_grizzly(true);
        Thread.sleep(4000);
    }

    @Before
    public void setUp() throws Exception {
        client = new Client();
        webResource = client.resource("http://localhost:8888");
    }   

    @Test
    public void testPostSchemaDatabase() throws Exception {
        {
            String DatabaseSchema = "{ database_schema : {...}}";
            logger.info("REST client configured to send: "  + DatabaseSchema);
            ClientResponse response =  
                    webResource
                             .path("/initialize")
                             .type("application/json")
                             .post(ClientResponse.class, DatabaseSchema);
            //wait for the server to process
            Thread.sleep(2000);
            assertEquals(response.getStatus(), 204);    
            //test the response
        }       
    }

    @After
    public void after() throws JSONException
    {
            //probably you want to delete the schema at database and stop the server

}
 0
Author: user311174, 2012-05-28 06:42:07