将模拟对象注入要在测试中声明为测试的对象的测试对象使用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() { ... } }