0

Class under test:

class FruitQuality {

  void testQuality() {
    getfruits();
    //some code
  }

  List<Fruits> getfruits() {
    return orange;
  }
}

Below is the test code. I mocked the class class under test and overridden a return value for the method getfruits. But when I run the mock, I don't get the expected mocked return value. Easymock can substitute return values for methods of class under test, if those are explicitly mocked. How can I get the mocked return value when I mock the real object method.

@Test
public void test() {
  Fruits fruit= new Fruits();
  fruit.setFruit("orange");
  List<Fruits> fruitsList = new ArrayList<Fruits>();
  fruitsList.add(fruit);

  Fruits mock = Mockito.mock(FruitQuality.class)
  classUnderTest = new FruitQuality();
  when(mock.getfruits()).thenReturn(fruitsList);

  result= classUnderTest.getfruits();
  assertEquals(result, fruitsList);
}
Basilevs
  • 22,440
  • 15
  • 57
  • 102
learningUser
  • 428
  • 3
  • 8
  • 21

1 Answers1

0

Typically, when writing unit tests, you have one class under test containing the implementation code you are testing, while mocking the methode of other classes your class under test is relying on.

Refering to your example you would have a class

public class FruitQuality {
    private FruitProvider fruitProvider;

    public List<Fruit> testQuality() {
        List<Fruit> fruits = fruitProvider.getfruits();
        /* Some code doing something with fruits, e.g., filtering. */
        return fruits;
    }
}

And a second class

public class FruitProvider {
    public List<Fruits> getfruits() {
        /* Returning some fruits ... */
    }
}

Now, you could mock your Provider to test your class under test:

@RunWith(MockitoJUnitRunner.class)
public class FruitQualityUnitTest {
    @InjectMocks
    private FruitQuality fruitQuality;
    @Mock
    private FruitProvider fruitProvider;

    @Test
    public void testQuality() {
        /* Mocking the provider. */
        Fruits fruit= new Fruits();
        fruit.setFruit("orange");
        List<Fruits> fruitsList = new ArrayList<Fruits>();
        fruitsList.add(fruit);
        when(fruitProvider.getFruits()).thenReturn(fruitsList);

        /* Invoke the method under test. */
        List<Fruits> result = fruitProvider.testQuality();

        /* Assert that some methods where called. */
        verify(fruitProvider, times(1)).getFruits();

        /* If the method would return a value, you can do some assertions based on the mocked method calls. */
        assertEquals(result, fruitsList);
    }
}

If you want to test methods of the same object you are mocking, you can use the @Spy annotation instead of @Mock, assuring that only methods you are explicitely mocking doing other things than the original implementation.

Claas Wilke
  • 1,951
  • 1
  • 18
  • 29