我有一个非常复杂的类来编写Junit测试用例。我决定使用PowerMockito,因为我要运行测试的类有一个构造函数初始化。
我的主要课程是这样的:
public class MainClass extends BaseClass{
MainClass(SomeClass class){
super(class);
}
public void methodToBeTested(){
some code here
}
..few other methods which I am not going to test.
}
现在我的测试用例如下:
@RunWith(PowerMockRunner.class)
public class TestClass{
@Mock
OtherClassUsedInMainClass mock1;
@Mock
OtherClassUsedInMainClass mock2;
@InjectMocks
MainClass mainClass;
@Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
PowerMockito.whenNew(MainClass.class).withArguments(Mockito.any(SomeClass.class))
.thenReturn(mainClass);)
}
@Test
public void testMethodtobeTested(){
...I am using the other objects to mock data and test if this method works fine
mainClass.methodtobeTested();
\\This method will increment a value. I am just asserting if that value is right.
Assert.assertEquals(mainClass.checkCount(),RequiredCount)
}
}
我在运行Testcase时遇到空指针异常,因为它尝试初始化 mainClass 。它不会被嘲笑。我知道我做错了什么。但我只是不知道它是什么。
错误:
org.mockito.exceptions.base.MockitoException:
Cannot instantiate @InjectMocks field named 'mainClass' of type 'class com.main.MainClass'.
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
Caused by: java.lang.NullPointerException
This null pointer exception is thrown from a the constructor of the BaseClass when it tries to initialize another class.
答案 0 :(得分:1)
This question解释了@Mock
和@InjectMocks
:
@Mock
创建了一个模拟。 @InjectMocks
创建该类的实例,并将使用@Mock
(或@Spy
)注释创建的模拟注入此实例。
MainClass
构造函数需要一个SomeClass
参数,但没有任何模拟。
您的代码应该是:
@RunWith(PowerMockRunner.class)
public class TestClass{
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
SomeClass mock1;
@InjectMocks
MainClass mainClass;
@Before
public void setUp() throws Exception{
...
答案 1 :(得分:0)
引用this answer引用@InjectMocks
documentation:
构造函数注入;选择最大的构造函数,然后使用在测试中声明的模拟来解析参数。注意:如果找不到参数,则传递null。
因此,可能会声明一个SomeClass
类型的字段,并对其进行注释@Mock
。
答案 2 :(得分:0)
如果您无法向我们展示实际代码,则很难猜出究竟发生了什么。但看起来你的模拟SomeClass
需要一些存根行为来满足BaseClass构造函数。
例如:
// the instance of MainClass you run your tests against
private MainClass instance;
@Mock
private SomeClass someClass;
@Mock
private SomethingElse somethingElse;
@Before
public void setUp() {
when(someClass.doSomething()).thenReturn(somethingElse);
instance = new MainClass(someClass);
}
@Test
public void test() {
// SETUP
when(somethingElse.doWeirdStuff()).thenThrow(new WeirdException());
// CALL
instance.performTapDance();
// VERIFY
assertTrue(instance.isWeird());
}