将模拟对象注入要在测试中声明为测试的对象的测试对象使用Mockito不起作用?

我有一个class级,我正在为我的服务注入代理。

Service service { private ServiceProxy proxy; public Service(ServiceProxy proxy) { this.proxy = proxy; } } 

对它的测试是:

 ServiceTest { @Mock ServiceProxy mockProxy; Service service = new Service(mockProxy); } 

如果我像这样初始化我的类,当我想使用服务对象时,我总是得到一个NPE 。 为什么Mockito这样做? 有什么方法可以解决这个问题,而不是在每次测试中声明它?

如果您使用Mockito版本1.9.0或更高版本,实现您想要的最佳方式是这样的:

 @RunWith(MockitoJUnitRunner.class) public class ServiceTest { @Mock private ServiceProxy proxy; @InjectMocks private Service service; @Test public void test() { assertNotNull(service); assertNotNull(proxy); } } 

首先是@RunWith(MockitoJUnitRunner.class)声明,它将导致@Mock和@InjectMocks注释自动工作,无需任何显式初始化。 第二件事是从Mockito 1.9.0开始@InjectMocks注释可以使用构造函数注入机制,这是您的Service类的最佳选择。

@InjectMocks的其他选项是Setter注入Field注入 (参见文档 BTW),但是你需要一个无参数构造函数来使用它们。

总结一下 – 你的代码无法工作,因为:

  • 你没有使用MockitoJUnitRunner和MockitoAnnotations.initMocks(这个)所以@Mock注释不起作用
  • 即使满足以上条件,您的示例也会失败,因为构造测试之后初始化mockProxy并且在测试类构造期间尝试初始化您的服务 ,因此它接收null mockProxy引用。

如果由于某种原因您不想使用@InjectMocks,唯一的方法是在测试方法体内或@Before带注释的setUp方法中构造Service对象。

编写您的测试类,它将使用ServiceProxy的模拟初始化Service

 class ServiceTest { @Mock ServiceProxy mockProxy; //This will inject the "ServiceProxy" mock into your "Service" instance. @InjectMocks Service service = new Service(mockProxy); @Before public void init() { //This will initialize the annotated mocks MockitoAnnotations.initMocks(this); } @Test public void test() { ... } }