0

How do I mockk a Bitmap without it breaking Bitmaps in future tests? Let's take the following simplified example...

class FileHelper @Inject constructor(private val application: Application) {
    fun saveBitmapToTempDirectory(bitmap: Bitmap, filename: String, format: Bitmap.CompressFormat): File {
        val tempDirectory = File(application.cacheDir, "images").apply { mkdirs() }
        val file = File(tempDirectory, "$filename.${format.name.toLowerCase()}")
        FileOutputStream(file).use { outStream ->
            bitmap.compress(format, 100, outStream)
        }
        return file
    }
}

Let's say may test class is as follows...

@RunWith(AndroidJUnit4::class)
class FileHelperTest {

    @Test
    fun otherTest(){
//        When I uncomment the next line, I get NoSuchMethodException: checkRecycled in testSaveBitmapToTempDirectoryWithSuccess()
//        val mockBitmap: Bitmap = mockk()
//        Do stuff using a mockBitmap

//        The following block also causes the same issue (even with a real decoded Bitmap).
//        mockkStatic(BitmapFactory::class)
//        every {
//            BitmapFactory.decodeStream(mockInputStream)
//        } returns realDecodedBitmap
//        unmockkStatic(BitmapFactory::class)

//        None of the following work:
//        unmockkAll()
//        clearAllMocks()
//        unmockkStatic(Bitmap::class)
//        clearMocks(mockBitmap)
//        clearStaticMockk(Bitmap::class)
    }

    @Test
    fun testSaveBitmapToTempDirectoryWithSuccess() {
        val application = InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application
        val file = FileHelper(application).saveBitmapToTempDirectory(
            BitmapFactory.decodeResource(application.resources, R.drawable.mypic),
            "bitmap",
            Bitmap.CompressFormat.PNG
        )
        assertTrue(file.absolutePath.endsWith("bitmap.png"))
    }
}

testSaveBitmapToTempDirectoryWithSuccess() passes if I run it alone. If I include the line that mockks a Bitmap (val mockBitmap: Bitmap = mockk()), then testSaveBitmapToTempDirectoryWithSuccess() fails when I run all the tests together. bitmap.compress() throws NoSuchMethodException: checkRecycled

Similarly, if another test class mockks a Bitmap and is run as a group with this test class, then testSaveBitmapToTempDirectoryWithSuccess() fails for the same reason.

How do I address this situation? In some tests, I'd like to have a mock Bitmap. In other tests, I'd like to compress a real one.

JHowzer
  • 3,684
  • 4
  • 30
  • 36
  • You've got a test that successfully creates an instance of `Bitmap` and passes. Why do you want to mock it in a different method in the same test file? – Egor Mar 13 '19 at 03:52
  • Good question. This example is a simplified version of something that I encountered when running multiple test files. The origin of problem started when test class A had a mockk of a Bitmap and test class B did something similar to what's in the example and I run A's tests and B's tests as a group. I mainly just put it into a single test class to make the example more simple and I stripped out a bunch of other code to isolate it to what was triggering the issue. – JHowzer Mar 13 '19 at 03:58
  • Got it. I'd recommend against mocking things like Bitmaps: it's a final class hence mockk has to perform weird bytecode manipulations to mock it. Just create test instances the way you already do. – Egor Mar 13 '19 at 04:04
  • `unmockkAll` should have been returned it to the original state. Also `unmockkObject` is suitable to revert `mockk`. If it is not working please submit an issue with detailed description to http://github.com/mockk/issues – oleksiyp Mar 13 '19 at 06:14
  • For anyone who happens to be interested... https://github.com/mockk/mockk/issues/270 – JHowzer Mar 13 '19 at 16:03

0 Answers0