Code inside mutex is not accounted for tests

59 views Asked by At

Why the following test fails when we use a mutex? How to solve it?

class ClassA {
  suspend fun return10(): String {
    delay(1000) // Assume some kind of operation
    return "10"
  }
}

object MyClass {

  private val mClassA by lazy { ClassA() }
  private val mMutex = Mutex()

  suspend fun performOperationWithMutex(): String {
    mMutex.withLock { 
      return mClassA.return10() 
    }
  }

  suspend fun performOperationWithoutMutex(): String = mClassA.return10()
}

@RunWith(RobolectricTestRunner::class)
@Config(application = TestApplication::class)
class MyTest {

  private val mMyClass = spyk<MyClass>()
  private val mClassA = mockk<ClassA>(relaxed = true, relaxUnitFun = true)

  @Before
  fun setUp() {
    every { mMyClass getProperty "mClassA" } returns mClassA
  }

  @ExperimentalCoroutinesApi
  @Test
  fun testWithoutMutexSucceeds() = runBlockingTest {
    mMyClass.performOperationWithoutMutex()
    coVerify (exactly = 1) { mClassA.return10() }
  }

  @ExperimentalCoroutinesApi
  @Test
  fun testWithMutexFails() = runBlockingTest {
    mMyClass.performOperationWithMutex()
    coVerify (exactly = 1) { mClassA.return10() }
  }
}

The test that fails says:

Verification failed: call 1 of 1: ClassA(#5).return10(any())) was not called
0

There are 0 answers