title: Hit with Unimplemented method StatusRuntimeException when unit testing generated grpc code in Android project
body: <p>I have an Android project that generates gRPC classes from the proto file upon building, which is from here under the helloworld example:
  <a href="https://github.com/grpc/grpc-java/tree/master/examples/src" rel="nofollow noreferrer">https://github.com/grpc/grpc-java/tree/master/examples/src</a></p>
  
  <p>My JUnit test follows to that of the test written for HelloWorldClient (<a href="https://github.com/grpc/grpc-java/blob/master/examples/example-kotlin/src/test/kotlin/io/grpc/examples/helloworld/HelloWorldClientTest.kt" rel="nofollow noreferrer">https://github.com/grpc/grpc-java/blob/master/examples/example-kotlin/src/test/kotlin/io/grpc/examples/helloworld/HelloWorldClientTest.kt</a>), and I thought it theoretically would work</p>
  
  <p>However, when I run the test, I was hit with an exception error as follows:</p>
  
  <pre><code>io.grpc.StatusRuntimeException: UNIMPLEMENTED: Method helloworld.Greeter/SayHello is unimplemented
      at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:235)
      at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:216)
      at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:141)
      at io.grpc.examples.helloworld.GreeterGrpc$GreeterBlockingStub.sayHello(GreeterGrpc.java:177)
      at com.android.grpcmvvm.data.GreeterRemoteDataSource.sayHello(GreeterRemoteDataSource.kt:49)
      at com.android.grpcmvvm.view.GreeterViewModelUnitTest.testTestFunction(GreeterViewModelUnitTest.kt:109)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at io.grpc.testing.GrpcCleanupRule$1.evaluate(GrpcCleanupRule.java:125)
      at org.junit.rules.RunRules.evaluate(RunRules.java:20)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
      at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  
  
  Wanted but not invoked:
  serviceImpl.sayHello(
      &lt;Capturing argument&gt;,
      &lt;any&gt;
  );
  -&gt; at io.grpc.examples.helloworld.GreeterGrpc$GreeterImplBase.sayHello(GreeterGrpc.java:101)
  
  However, there was exactly 1 interaction with this mock:
  serviceImpl.bindService();
  -&gt; at io.grpc.internal.AbstractServerImplBuilder.addService(AbstractServerImplBuilder.java:114)
  
  
  Wanted but not invoked:
  serviceImpl.sayHello(
      &lt;Capturing argument&gt;,
      &lt;any&gt;
  );
  -&gt; at io.grpc.examples.helloworld.GreeterGrpc$GreeterImplBase.sayHello(GreeterGrpc.java:101)
  
  However, there was exactly 1 interaction with this mock:
  serviceImpl.bindService();
  -&gt; at io.grpc.internal.AbstractServerImplBuilder.addService(AbstractServerImplBuilder.java:114)
  
  
      at io.grpc.examples.helloworld.GreeterGrpc$GreeterImplBase.sayHello(GreeterGrpc.java:101)
      at com.android.grpcmvvm.view.GreeterViewModelUnitTest.testTestFunction(GreeterViewModelUnitTest.kt:112)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
      at io.grpc.testing.GrpcCleanupRule$1.evaluate(GrpcCleanupRule.java:125)
      at org.junit.rules.RunRules.evaluate(RunRules.java:20)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
      at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
      at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
      at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
      at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
      at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
  </code></pre>
  
  <p>The following is the test and the relevant code
  (Please mind the ViewModel name. I removed anything about ViewModel from the test for the purpose of this question)</p>
  
  <p><strong>GreeterViewModelUnitTest.kt</strong></p>
  
  <pre><code>import com.android.grpcmvvm.data.GreeterRemoteDataSource
  import com.android.grpcmvvm.grpc.GrpcService
  import io.grpc.ManagedChannel
  import io.grpc.examples.helloworld.GreeterGrpc
  import io.grpc.examples.helloworld.HelloReply
  import io.grpc.examples.helloworld.HelloRequest
  import io.grpc.inprocess.InProcessChannelBuilder
  import io.grpc.inprocess.InProcessServerBuilder
  import io.grpc.stub.StreamObserver
  import io.grpc.testing.GrpcCleanupRule
  import org.junit.Assert.assertEquals
  import org.junit.Before
  import org.junit.Rule
  import org.junit.Test
  import org.junit.runner.RunWith
  import org.junit.runners.JUnit4
  import org.mockito.*
  import org.mockito.AdditionalAnswers.delegatesTo
  import org.mockito.internal.matchers.Any
  
  @RunWith(JUnit4::class)
  class GreeterViewModelUnitTest {
      // region JUnit test rules
      @get:Rule
      val grpcCleanupRule = GrpcCleanupRule()
  
      private val serviceImpl = Mockito.mock(GreeterGrpc.GreeterImplBase::class.java, delegatesTo&lt;Any&gt;(object: GreeterGrpc.GreeterImplBase(){}))
      // endregion
  
      // region Private properties
      @Mock
      private lateinit var grpcService: GrpcService
  
      private lateinit var managedChannel: ManagedChannel
  
      private lateinit var greeterRemoteDataSource: GreeterRemoteDataSource
      // endregion
  
      @Before
      @Throws(Exception::class)
      fun setUp() {
          MockitoAnnotations.initMocks(this)
  
          val serverName = InProcessServerBuilder.generateName()
  
          grpcCleanupRule.register(InProcessServerBuilder
              .forName(serverName)
              .directExecutor()
              .addService(serviceImpl)
              .build()
              .start())
  
          managedChannel = grpcCleanupRule.register(InProcessChannelBuilder
              .forName(serverName)
              .directExecutor()
              .build())
  
          Mockito.`when`(grpcService.createManagedChannel()).thenReturn(managedChannel)
          greeterRemoteDataSource = GreeterRemoteDataSource(grpcService)
      }
  
      @Test
      fun testTestFunction() {
          val requestCaptor = ArgumentCaptor.forClass(HelloRequest::class.java)
  
          greeterRemoteDataSource.sayHello("once again")
  
          Mockito.verify&lt;GreeterGrpc.GreeterImplBase&gt;(serviceImpl)
              .sayHello(requestCaptor.capture(), ArgumentMatchers.any&lt;StreamObserver&lt;HelloReply&gt;&gt;())
  
          assertEquals("once again", requestCaptor.value.name)
      }
  </code></pre>
  
  <p><strong>GrpcService.kt</strong></p>
  
  <pre><code>import io.grpc.ManagedChannel
  import io.grpc.ManagedChannelBuilder
  import java.util.concurrent.Executors
  
  class GrpcService(private val host: String, private val port: Int) {
  
      fun createManagedChannel(): ManagedChannel {
          return ManagedChannelBuilder
              .forAddress(host, port)
              .executor(Executors.newSingleThreadExecutor())
              .usePlaintext()
              .build()
      }
  }
  </code></pre>
  
  <p><strong>GreeterRemoteDataSource.kt</strong></p>
  
  <pre><code>import com.android.grpcmvvm.grpc.GrpcService
  import io.grpc.ManagedChannel
  import io.grpc.StatusRuntimeException
  import io.grpc.examples.helloworld.GreeterGrpc
  import io.grpc.examples.helloworld.HelloReply
  import io.grpc.examples.helloworld.HelloRequest
  
  class GreeterRemoteDataSource constructor(private val grpcService: GrpcService) {
  
      private lateinit var channel: ManagedChannel
  
      fun sayHello(message: String): String {
          channel = grpcService.createManagedChannel()
  
          val stub = GreeterGrpc.newBlockingStub(channel)
          val request = HelloRequest.newBuilder().setName(message).build()
  
          val reply: HelloReply = try {
              stub.sayHello(request)
          } catch (e: StatusRuntimeException) {
              e.printStackTrace()
              return String.format("{0}", e.status)
          } finally {
              channel.shutdown()
          }
  
          return reply.message
      }
  }
  </code></pre>
  
  <p><strong>build.gradle (app)</strong></p>
  
  <pre><code>apply plugin: 'com.android.application'
  
  apply plugin: 'com.google.protobuf'
  
  apply plugin: 'kotlin-android'
  
  apply plugin: 'kotlin-android-extensions'
  
  android {
      compileSdkVersion 28
      defaultConfig {
          applicationId "com.android.grpcmvvm"
          minSdkVersion 15
          targetSdkVersion 28
          multiDexEnabled true
          versionCode 1
          versionName "1.0"
          testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
      }
      buildTypes {
          release {
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
          }
      }
  }
  
  dependencies {
      def grpc_version = "1.22.1"
      def lifecycle_version = "2.2.0-alpha04"
      def mockito_kotlin_version = "2.1.0"
      def mockito_version = "3.0.0"
      def multidex_version = "2.0.1"
      def truth_version = "0.45"
  
      implementation fileTree(dir: 'libs', include: ['*.jar'])
      implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  
      implementation 'androidx.core:core-ktx:1.1.0'
      implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
      implementation "androidx.multidex:multidex:$multidex_version"
      implementation 'com.google.android.material:material:1.0.0'
  
      // gRPC
      implementation 'javax.annotation:javax.annotation-api:1.3.2'
      implementation "io.grpc:grpc-okhttp:$grpc_version"
      implementation "io.grpc:grpc-protobuf-lite:$grpc_version"
      implementation "io.grpc:grpc-stub:$grpc_version"
  
      // Lifecycle
      implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
  
      // Instrumented tests
      androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
      androidTestImplementation 'androidx.test:runner:1.2.0'
  
      // Unit tests
      testImplementation "androidx.arch.core:core-testing:2.1.0"
      testImplementation "com.google.truth:truth:$truth_version"
      testImplementation "io.grpc:grpc-testing:$grpc_version"
      testImplementation "com.nhaarman.mockitokotlin2:mockito-kotlin:$mockito_kotlin_version"
      testImplementation 'junit:junit:4.12'
      testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.3.1'
      testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.1'
      testImplementation "org.mockito:mockito-inline:$mockito_version"
  }
  
  protobuf {
      protoc {
          artifact = 'com.google.protobuf:protoc:3.9.0'
      }
      plugins {
          grpc {
              artifact = "io.grpc:protoc-gen-grpc-java:1.22.1"
          }
          javalite {
              artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
          }
      }
      generateProtoTasks {
          all()*.plugins {
              javalite {}
          }
          ofNonTest()*.plugins {
              grpc {
                  // Options added to --grpc_out
                  option 'lite'
              }
          }
      }
  }
  </code></pre>
  
  <p><strong>build.gradle</strong></p>
  
  <pre><code>// Top-level build file where you can add configuration options common to all sub-projects/modules.
  
  buildscript {
      ext.kotlin_version = '1.3.50'
      repositories {
          google()
          jcenter()
  
      }
      dependencies {
          classpath 'com.android.tools.build:gradle:3.5.0'
          classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.10'
          classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
          // NOTE: Do not place your application dependencies here; they belong
          // in the individual module build.gradle files
      }
  }
  
  allprojects {
      repositories {
          google()
          jcenter()
  
      }
  }
  
  task clean(type: Delete) {
      delete rootProject.buildDir
  }
  </code></pre>
  
  <p>I'm currently unable to find what exactly would cause such an error. I've also looked around for answers/insights to no avail.</p>
  
  <p>Any input is appreciated.</p>