使用 Mockito 进行测试时,使用实现而不是接口是一种好习惯吗?

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

Mockito 注释 @Spy@InjectMocks 不适用于接口:

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
}

来自 Spy 的文档(与 @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.

所以我知道我不能使用接口来监视。当我使用实际实现 class 当 declaring/initializing 接口时,它会起作用。

下面哪种解决方案最适合处理此类问题?

解决方案一:

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

方案二:

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

我的问题是使用解决方案 2 并让 Mockito 处理实例化(但这意味着声明一个实现而不是接口)或使用带有接口的解决方案 1 并自己声明一个实现是否是个好主意.

感谢大家的回复。这对我帮助很大。我现在就结束这个问题。

基本上我应该针对实现进行测试。我还想参考 this question,其中包含一些更有用的信息。