2016-08-05 2 views
1

이 질문을 둘러 보았고 필요한 정보를 찾지 못했습니다. 나는 JMockit과 조롱에 대해 조금 더 배웠다. 어느 것이 좋니. 모두가 뭔가가 실행되었는지 확인하는 방법을 알고 싶어하는 것처럼 보입니다. 나는 그 반대를 배우고 싶다.개인 메서드가 실행되지 않았는지 확인하십시오. JMockit

Ok - 공개 메소드에서 그리 그리 행복하지 않은 경로를 검사하는 테스트를 작성하고 있습니다. 테스트중인 메서드는 void이므로 실제로는 assert 결과를 얻을 수 없습니다. 제가하고 싶은 것은이 테스트 케이스에서 메소드가 실행되지 않았 음을 확인하는 것입니다. 예를 들어

:

class ClassToTest { 
    private void method(String arg){} 

    public void publicMethod(String arg0, String arg1){ 
    if(false){ 
     //this method should never get called. 
     method(arg0); 
    } 
    } 
} 

class TestingClass{ 
    @Tested 
    private ClassToTest classToTest = new ClassToTest(); 

    @Test 
    public void testCheckingIfPrivateMethodWasCalled(){ 
    classToTest.publicMethod("string1", "string2"); 

    new Verifications() { 
     { 
     //At this point I am trying something like 
     Deencapsulation.invoke(classToTest, "method", "string1"); 
     times = 0; //Also tried maxTimes = 0; 
     //Through debug it looks like the invoke is doing what it's named... 
     //invoking the private method, I don't want to invoke. 
     //How do I check that ClassToTest#method was not called? 
     } 
    } 
    } 
} 

는 내가 테스트 케이스에 대한 결과로 얻고 것은 java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter이다. 어느 라인에 times = 0;입니다.

나는 invoke이 (가) 개인적인 방법을 실행하고 있음을 알고 있습니다. 나는 내 머리를 긁어내어 메서드가 호출/실행되지 않고 호출되는 것을 "확인"하는 방법을 알아 내려고 노력하고있다.

감사합니다. 그 일의

+2

테스트 응용 프로그램의 상태. 개인 메소드의 호출이 중요한 경우, 어딘가에 영향을 미쳐야하고 테스트 할 수 있어야합니다. 이를 막기 위해, 메소드가 기본 가시성 (일명 패키지로 보호 됨)을 제공하여 테스트에서이를 확인할 수 있도록하는 것이 좋습니다. (테스트는 테스트중인 클래스와 동일한 패키지에 있다고 가정합니다. 이는 합리적인 가정입니다.) – nasukkin

+0

* 결코 'private'메소드를 모의하지 마십시오. 그렇게 할 이유가 없습니다. 그것에 대해 생각해보십시오. 개인 메서드는 품질을 신경 쓰는 개발자가 언제든지 만들거나 인라인 할 수 있습니다. 기능 보존 형 리팩터링을 통해 생산 코드를 향상시키는 동안 실제 작동 테스트를 수정해야할까요? 당신이 그것에 대해 신경 쓰지 않는다 할지라도, 팀 내의 또는 앞으로의 다른 개발자들도 고려해야합니다. –

답변

0

한 가지 방법은 faking의 모형 API를이다 :

import static org.junit.Assert.assertFalse; 

import org.junit.Test; 

import mockit.Mock; 
import mockit.MockUp; 
import mockit.Tested; 

public class TestingClass { 

    @Tested 
    private ClassToTest classToTest = new ClassToTest(); 

    @Test 
    public void testCheckingIfPrivateMethodWasCalled() { 
     PrivateMethodCheckMockUp mockUp = new PrivateMethodCheckMockUp() { 
      @Mock 
      private void method(String arg) { 
       calledPrivate = true; 
      } 
     }; 

     classToTest.publicMethod("string1", "string2"); 

     assertFalse(mockUp.calledPrivate); 
    } 

    class PrivateMethodCheckMockUp extends MockUp<ClassToTest> { 
     boolean calledPrivate = false; 

     @Mock 
     private void method(String arg) { 
      calledPrivate = true; 
     } 
    } 
} 
+0

그러면 클래스의 인스턴스를 조롱하고 해당 클래스의 메소드를 조롱하는 것입니까? 'PrivateMethodCheckMockUp # method'를 두 번 조롱합니까? –

+0

실제로'ClassToTest'는 한 번만 조롱됩니다.'@Tested'는 모의 객체를 생성하지 않습니다. "JMockit은 자동으로이 클래스를 인스턴스화하고, 관련 mocked 종속성을 선택적으로 주입하여 도움을 줄 수 있습니다.이 것이 @Tested 주석의 용도입니다." – Alfergon

+0

그럼'MockUp' API를 사용하여 개인 메소드를 조롱하고 호출되었는지 여부를 알 수있는 플래그를 사용합니다 (아마 Assert.fail()이 충분할 것입니다). – Alfergon