MVVM on Android · Testing the ViewModel | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/8984-mvvm-on-android/lessons/7

Hi. I had a doubt about the test because if I change the name on the viewmodel like viewModel.name = “some creature” the test should fail since the name is different from the stubCreature but that is not with the mock. Shouldn’t we use something like

when(mockGenerator.generateCreature(attributes, “CreatureName”)).thenReturn(stubCreature)

This test fails due to the Mockito method matcher does not match the call.

@Test
    fun testSetupCreature() {
        val attributes = CreatureAttributes(10, 3, 7)
        val stubCreature = Creature(attributes, 87, "Test")
        `when`(mockGenerator.generateCreature(attributes)).thenReturn(stubCreature)

        creatureViewModel.intelligence = 10
        creatureViewModel.strength = 3
        creatureViewModel.endurance = 7
        creatureViewModel.name = "Test"

        creatureViewModel.updateCreature()

        assertEquals(stubCreature, creatureViewModel.creature)
    }

This one passes, but if I change the name of the stub creature, it will still pass.
I could not think about a nice way to let it clear that the name of the creature on the ViewModel matters.

@Test
    fun testSetupCreature() {
        val attributes = CreatureAttributes(10, 3, 7)
        val stubCreature = Creature(attributes, 87, "Test")
        `when`(mockGenerator.generateCreature(eq(attributes), eq("Test"), anyInt())).thenReturn(stubCreature)

        creatureViewModel.intelligence = 10
        creatureViewModel.strength = 3
        creatureViewModel.endurance = 7
        creatureViewModel.name = "Test"

        creatureViewModel.updateCreature()

        assertEquals(stubCreature, creatureViewModel.creature)
    }

This one works as well, but still will throw an unrelated error if we change the creatureViewModel.name value

    @Test
    fun testSetupCreature() {
        val attributes = CreatureAttributes(10, 3, 7)
        val stubCreature = Creature(attributes, 87, "Test")
        `when`(mockGenerator.generateCreature(attributes, "Test", 0)).thenReturn(stubCreature)

        creatureViewModel.intelligence = 10
        creatureViewModel.strength = 3
        creatureViewModel.endurance = 7
        creatureViewModel.name = "Test"

        creatureViewModel.updateCreature()

        assertEquals(stubCreature, creatureViewModel.creature)
    }

Thanks for the question, Amadeu!

I think your third example is the best version of this test. The point of this test is to ensure that the updateCreature() method is correctly calling the CreatureGenerator to update the creature. Your third example does this most explicitly. A better name for that test in the video would have been something like testUpdateCreatureCorrectlyUpdatesCreature().

Thanks again!

1 Like