Fadelis / grpcmock

A gRPC Java testing tool to easily mock endpoints of gRPC services for IT or Unit testing
http://grpcmock.org
Apache License 2.0
144 stars 13 forks source link

Support for future stubs #27

Closed dshaver1 closed 1 year ago

dshaver1 commented 1 year ago

I'm attempting to write a test case utilizing an AbstractFutureStub and am running into an issue chaining multiple responses. Basically all calls to the future stub return the initial response and never the 'next' response:

    stubFor(unaryMethod(TestingServiceGrpc.getCreateMethod())
        .willReturn(response(WorkflowTracker.newBuilder()
            .setId("id1")
            .setClientId("clientId1")
            .build()).withFixedDelay(Duration.ofMillis(200)))
        .nextWillReturn(response(WorkflowTracker.newBuilder()
            .setId("id2")
            .setClientId("clientId2")
            .build())));

    ListenableFuture<WorkflowTracker> fut1 = stub.create(CreateRequest.newBuilder().build());
    ListenableFuture<WorkflowTracker> fut2 = stub.create(CreateRequest.newBuilder().build());

    try {
      WorkflowTracker tracker1 = fut1.get();
      WorkflowTracker tracker2 = fut2.get();
      assertNotEquals(tracker1, tracker2);
    } catch (Exception e) {
      fail();
    }

But the exact same test using an AbstractBlockingStub works as expected, where the first call to create returns the first response, and the second call to create returns the second response. Is it expected that we should be able to mock sequential responses with a AbstractFutureStub?

In my app I will be firing off many requests in parallel and I'd like to get unique responses for each request, but not sure how to simulate this. Note that if I move the fut1.get() above the second stub.create() it works as expected... but this is not how my app will be calling the stub so it would not be an accurate test. The below test works as expected since I presume it's more similar to a blocking stub.

      ListenableFuture<WorkflowTracker> fut1 = stub.create(CreateRequest.newBuilder().build());
      WorkflowTracker tracker1 = fut1.get();
      ListenableFuture<WorkflowTracker> fut2 = stub.create(CreateRequest.newBuilder().build());
      WorkflowTracker tracker2 = fut2.get();
dshaver1 commented 1 year ago

Closing this as I almost immediately discovered how to get it to work: specify unique .withRequest(expectedRequest1) in my stubs, so that each request only matches 1 possible stubbed response.