2016-07-20 3 views
1

Junit 테스트 케이스를 작성하는 데 매우 복잡한 클래스가 있습니다. 테스트를 수행 할 클래스에는 생성자 초기화가 있으므로 PowerMockito를 사용하기로 결정했습니다.InjectMocks 오류를 사용하는 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) 

} 

} 

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

는 BaseClass로의 생성자를 표시합니다. 오류가 발생했습니다 – Jens

+0

왜 MainClass를 스터 빙하고 있습니까? 당신이 테스트하는 수업이 아닌가요? –

+0

@Jens 기본 클래스 생성자는 mainClass에서 전달 된 someClass를 인수로 취합니다. 또한이 someClass를 사용하고 someClass를 사용하는 생성자를 가진 몇몇 다른 클래스를 초기화하는 데이 클래스를 사용합니다. – v1shnu

답변

0

@InjectMocks documentation을 인용되는, this answer을 인용 :

Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. Note: If arguments can not be found, then null is passed.

그래서, 아마도, 유형 SomeClass의 필드를 선언하고 @Mock을 주석을 달 수 있습니다.

@Mock는 모의 작성

1

This question@Mock@InjectMocks의 차이를 설명한다. @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{ 
    ... 
+0

나는 이것을했다. 그러나 여전히 코드는 BaseClass에 포함됩니다. 초기화를 시도 할 때 BaseClass에서 널 포인터를 다시 얻습니다. – v1shnu

+0

@ViChU 저는 이것이 다른 것으로 생각합니다. 기본 클래스가 그 모의를 사용하는 방식과 관련이 있습니다. 아마도 SomeClass의 메서드에서 반환 객체를 사용하여 무언가를하고있을 것입니다. @Mock (answer = Answers.RETURNS_DEEP_STUBS) – user1121883

+0

을 사용해 보았습니다. 그것은 여전히 ​​BaseClass에서 null을 던집니다.MainClass const가 super (someClass)를 호출하면 someClass로 BaseClass const를 호출합니다. 생성자 내부에는 몇 가지 객체가 생성됩니다. someClass 객체에 액세스하는 반면 someClass 객체는 someClass를 생성자에서 사용합니다. – v1shnu

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()); 
}