5

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

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

对它的测试是:

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

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

4

2 回答 2

9

如果您使用的是 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 的其他选项是Setter 注入字段注入(请参阅文档BTW),但您需要一个无参数构造函数才能使用它们。

总结一下-您的代码无法正常工作,因为:

  • 您没有使用 MockitoJUnitRunner 或 MockitoAnnotations.initMocks(this) 所以 @Mock 注释无效
  • 即使满足上述要求,您的示例也会失败,因为mockProxy将在构建测试初始化,并且在测试类构建期间尝试初始化您的服务,因此它接收 null mockProxy引用。

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

于 2013-10-26T18:17:29.000 回答
3

像这样编写您的测试类,它将Service使用以下模拟进行初始化ServiceProxy

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() {
... 
}
}
于 2013-10-25T02:46:00.713 回答