Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stub classes shouldn't be final to allow mocking #2160

Closed
anuraaga opened this issue Aug 15, 2016 · 5 comments
Closed

Stub classes shouldn't be final to allow mocking #2160

anuraaga opened this issue Aug 15, 2016 · 5 comments

Comments

@anuraaga
Copy link
Contributor

#2077 Seems to have made stub classes final. As stubs do remote calls, it's usually important for them to be mockable to write unit tests, but mockito can't mock final classes. Previously users could use the interface I guess. While I understand the reasoning of dropping the interface for service classes in #1469, to allow stub upgrades without breaking service implementation code compile, does this apply to client stubs too? It'd be nice for the stub classes to either be non-final or have interfaces to allow mocking.

@ejona86
Copy link
Member

ejona86 commented Aug 15, 2016

It was never our intention to allow mocking the stubs. Any time Mockito does its hacks to mock classes that shouldn't be mocked (like if they only have private constructors, like AbstractStub) it opens the door to us breaking your test. We can't support tests that use Mockito to avoid API restrictions.

#1469 (comment) has some specific issues with mocking the stub. Instead of mocking the stub, we would suggest you to mock a service implementation and use InProcess transport for connecting the two. If you use directExecutor() for both client and server, all the calls happen immediately and within the testing thread.

If there are use cases that are poorly supported or utilities that could be useful (like #2051), we'd be happy to hear about them.

@ejona86 ejona86 closed this as completed Aug 15, 2016
@srivastavag
Copy link

This thread is somewhat dated so not sure if info is upto but cant StubInterface be used for mocking ?
Thanks

@ejona86
Copy link
Member

ejona86 commented Aug 29, 2017

@srivastavag, there isn't a StubInterface in the Java generated code.

@srivastavag
Copy link

Oops, I was looking for c++, extremely sorry for my oversight.

@ensonic
Copy link

ensonic commented Mar 2, 2018

@ejona86 All the linked examples assume you mock the service you are testing, which sounds weird to me (see https://github.com/grpc/grpc-java/blob/master/examples/src/test/java/io/grpc/examples/helloworld/HelloWorldClientTest.java)
My grpc service talks to other grpc services and I'd like to mock out those. My Dagger module injects those secondary grpc service stubs and hence in the Test dagger module I'll need to provide mocked stubs and this is when things seem to fall apart.

I understand your suggestion to mock the impl instead, but I am not sure how to actually make this work. I have this code:

@Module
public class XyzTestModule {

  @Provides
  BindableService provideXzyGrpcService(Datastore datastore) {
    GrpcServerRule grpcServerRule = new GrpcServerRule().directExecutor();
    AbcGrpc.AbcImplBase abcImpl =
      mock(AbcGrpc.AbcImplBase.class, delegatesTo(new AbcGrpc.AbcImplBase() {}));

    grpcServerRule.getServiceRegistry().addService(abcImpl);
    AbcGrpc.AbcBlockingStub abcClient =  AbcGrpc.newBlockingStub(grpcServerRule.getChannel());

    return new XyzService(datastore, abcClient);
  }
}

but get NullPointerExceptions for grpcServerRule.getServiceRegistry().addService(abcImpl); and this is probably because I run this outside of the @rule and the GrpcServerRule might need to be started or something (probably whatever the protected before() method does). Getting some real-world example would be awesome, since this is not obvious.

It looks like I'll have to replicate most of what is in https://github.com/grpc/grpc-java/blob/master/testing/src/main/java/io/grpc/testing/GrpcServerRule.java, right?

@lock lock bot locked as resolved and limited conversation to collaborators Sep 28, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants