jeudi 28 avril 2016

Is it good practice to use an Implementation instead of an Interface when testing with Mockito?

Mockito annotations @Spy or @InjectMocks won't work on Interfaces:

public interface MyService() {}

public class MyServiceImpl implements MyService {}


@RunWith(MockitoJUnitRunner.class)
public class MyServiceTest {

    @Spy
    @InjectMocks
    private MyService myService; // won't work

    @Mock
    MyDao myDao;

    // tests
}

From the documentation on Spy (something similar for @InjectMocks):

The field annotated with @Spy can be initialized by Mockito if a zero argument constructor can be found in the type (even private). But Mockito cannot instantiate inner classes, local classes, abstract classes and interfaces. The field annotated with @Spy can be initialized explicitly at declaration point. Alternatively, if you don't provide the instance Mockito will try to find zero argument constructor (even private) and create an instance for you. But Mockito cannot instantiate inner classes, local classes, abstract classes and interfaces.

So I understand that I cannot use an Interface to Spy on. It works when I use an actual implementation class when declaring/initializing the Interface.

Which of the solutions below would be the best to deal with these kind of issues?

Solution 1:

    @Spy
    @InjectMocks
    private MyService myService = new MyServiceImpl(); // Program against Interface

Solution 2:

    @Spy
    @InjectMocks
    private MyServiceImpl myService; // Program against implementation

My question is whether it's a good idea to use solution 2 and let Mockito handle the instantiation (but that means declaring an implementation instead of an interface) OR use solution 1 with an interface and do the declaration of an implementation myself.

Aucun commentaire:

Enregistrer un commentaire