2013-12-12 47 views
0

我有三个班ABC类:如果我写一个单元测试为A,看起来像的Mockito无法实例测试

public class A { 
    @Autowired 
    private B someB; 
    private C someC = someB.getSomeC(); 
} 

@Service 
public class B { 
    C getSomeC() { 
    return new C(); 
    } 
} 

public class C { } 

现在:

@RunWith(MockitoJUnitRunner.class) 
public class ATest { 

    @InjectMocks 
    private A classUnderTest; 

    @Mock 
    private B someB; 

    @Mock 
    private C someC; 

    @Test 
    public void testSomething() { 

    } 
} 

Mockito对此不满意:

org.mockito.exceptions.base.MockitoException: 
    Cannot instantiate @InjectMocks field named 'classUnderTest' of type 'class my.package.A'. 
    You haven't provided the instance at field declaration so I tried to construct the instance. 
    However the constructor or the initialization block threw an exception : null 

如果我删除呼叫A类,使得类A如下所示:

public class A { 
    private B someB; 
    private C someC; 
} 

,是的Mockito能够实例化classUnderTest和测试贯穿。

为什么会出现这种情况?

编辑:使用1.9.5的Mockito

回答

4

嗯,这是总是要失败:

public class A { 
    private B someB; 
    private C someC = someB.getSomeC(); 
} 

你试图调用getSomeC()上的值将始终是null ...总是会抛出NullPointerException。您需要修复A以更好地处理依赖关系。 (就我个人而言,我会将它们作为构造参数,但当然还有其他选项...)

+0

我忘了添加spring注释,someB是自动装配的,请参见上文。 – ptikobj

+0

@ptikobj:在实例变量初始化器运行之前,它不会被自动装入*是吗?即使Spring设法在'someC'字段初始化器执行之前自动调用'someB'字段,您认为Mockito能够执行相同的技巧吗?我不认为有一个类,如果没有抛出异常,你就无法正常调用构造函数,这不是一个好主意...... –

+0

我没有意识到自动装配和构造函数调用的顺序。这也被讨论了,例如[这里](http://stackoverflow.com/questions/6335975/autowired-bean-is-null-when-referenced-in-the-constructor-of-another-bean)。 – ptikobj