jmockit / jmockit1

Advanced Java library for integration testing, mocking, faking, and code coverage
Other
461 stars 239 forks source link

Expectations API: result order is not as expected #145

Closed marcdonovan closed 9 years ago

marcdonovan commented 9 years ago

import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.Response;

import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future;

public final class MethodUnderTest {

public void getId() throws ClientException {
    try {
        AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
        Future<Response> future = asyncHttpClient.prepareGet("").execute();
        Response response = null;
        try {
            response = future.get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        int code = response.getStatusCode();
        System.out.println(code);
        future = asyncHttpClient.prepareGet("").execute();
        try {
            response = future.get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        code = response.getStatusCode();
        System.out.println(code);
    } catch (IOException | ExecutionException e) {
        // do something
    }
}

}

/////////////////////////////////////////////

import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.ListenableFuture; import com.ning.http.client.Response; import mockit.Expectations; import mockit.Mocked; import org.testng.annotations.Test;

public class TestCode {

@Mocked
AsyncHttpClient asyncHttpClient;
@Mocked
AsyncHttpClient.BoundRequestBuilder boundRequestBuilder;
@Mocked
ListenableFuture<Response> listenableFuture;

@Test
public void testHappyPathWithCopierNotYetExistsInCourseCopy(@Mocked final Response response) throws Exception {

    new Expectations() {
        {
            new AsyncHttpClient();
            asyncHttpClient.prepareGet(anyString);
            result = boundRequestBuilder;
            boundRequestBuilder.execute();
            result = listenableFuture;
            listenableFuture.get();
            result = response;
            response.getStatusCode();
            result = 200;
            asyncHttpClient.prepareGet(anyString);
            result = boundRequestBuilder;
            boundRequestBuilder.execute();
            result = listenableFuture;
            listenableFuture.get();
            result = response;
            response.getStatusCode();
            result = 201;
        }
    };

    MethodUnderTest plugin = new MethodUnderTest();
    plugin.getId();

}

}

I expect the System to print out 200 first, then 201. Actual result is 201 then 201. It looks like the later result = 201 is overwriting the earlier 200. If I comment out the result = 201 line, then I get 200 output.

java version "1.7.0_55" OSX Darwin 13.1.0 JMockit 1.13 TestNG 6.8.17

rliesenfeld commented 9 years ago

Yes, the second expectation on "response.getStatusCode()" overwrites the first one. So, record just one expectation (and taking advantage of cascaded mocking):

@Mocked AsyncHttpClient asyncHttpClient;
@Mocked ListenableFuture<Response> listenableFuture;

@Test
public void testHappyPathWithCopierNotYetExistsInCourseCopy(@Mocked final Response response) throws Exception
{
    new Expectations() {{
         listenableFuture.get(); result = response;
         response.getStatusCode(); returns(200, 201);
    }};

    MethodUnderTest plugin = new MethodUnderTest();
    plugin.getId();
}