2013-10-25 38 views
4

我有一个班,我正在向我的服务注入代理。将Mock对象注入到被测试的对象中声明为测试中的字段不能使用Mockito?

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

它的测试是:

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

如果我初始化这样我的课,我总是得到一个NPE时,我想使用的服务对象。为什么Mockito这样做?什么是简单的方法,而不是在每个测试中都声明它?

+0

你可以包括你的NPE的堆栈吗?如果你想经常重新创建,那么测试工具类中的方法怎么样? – Taylor

+0

您是使用'MockitoJUnitRunner',还是使用'initMocks'来创建您的模拟? –

回答

4

您使用的版本的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注释开始,可以使用构造函数注入机制,这是您的服务类的最佳选项。

为@InjectMocks其他选项是二传手注射字段注入(见docs BTW),但你需要一个无参数的构造函数来使用它们。

所以总结 - 因为你的代码不能工作:

  • 您不使用MockitoJUnitRunner也不MockitoAnnotations.initMocks(本),所以@Mock注释将不起作用
  • 即使上述被满足您的例子将失败,因为mockProxy将被初始化后测试构造和您的服务试图测试类施工过程中被初始化,因此它接收空mockProxy参考。

如果你不想使用@InjectMocks某些原因,唯一的办法就是在测试方法体内或@Before注解setUp方法内构建你服务对象。

1

编写测试类,因为这,这将初始化ServiceServiceProxy一个模拟:

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() { 
... 
} 
} 
+0

为什么我需要使用initMocks。如果我不使用它并创建服务实例,那么只需声明@Mock作品。为什么? – Phoenix

+0

btw这不起作用 – Phoenix

+0

'@ Mock'定义了模拟对象。 '@InjectMocks'定义了模拟对象需要注入的地方。现在你需要一些类型的注释处理器来处理这个类中的注释,这样'Mockito'实际上可以将'@ Mock'对象注入到'@InjectMocks'中。这部分是由“MockitoAnnotations”播放的。initMocks(this);' –