2014-03-13 2 views
2

mockito.spy 방식에 문제가 있습니다.모키토 스파이 방식이 작동하지 않습니다.

나는 최근에 "오래된"프로젝트에 도착 해요 내 첫 번째 작업은 그 안에 mockito을 추가하고, 실제 단위 테스트 :

프로젝트를하는 것입니다 여기에 많은 개념의 문제 만이 아니 지점을 가지고 ;)

내가 내 문제 설명 : 나는 단지 executeTiti을 테스트 할 내 테스트 클래스 TitiTest.java에서 클래스

public class Tutu{ 
    public Tutu(){ 
    } 
} 

public class Toto{ 
    public Toto(){ 
    } 
    public int executeToto(Tutu tutu){ 
    //do some stuff 
    return 5; 
    } 
} 

public class Titi{ 
    private Toto toto; 

    public Titi(){ 
    this.toto = new Toto();  
    } 

    public void executeTiti(){ 
     //do some stuff 
     Tutu tutu = new Tutu(); 
     int ret = this.toto.executeToto(tutu); 
     //do some stuff 
    } 
} 

를, 내가 원하지 않는 이 클래스는 자체 테스트 클래스 TotoTest.java이기 때문에 executeToto 물건을 테스트 할 수있다.

(나는 내 ​​테스트에도 PowerMock을 사용하고 있으므로 PowerMockRunner를 사용하고 있지만 PowerMockRunner를 사용하지는 않습니다. 문제)

@RunWith(PowerMockRunner.class) 
public class TitiTest { 

@Test 
public void testExecuteTiti(){ 
    Toto toto = Mockito.spy(new Toto()); 
    Mockito.doReturn(2).when(toto).executeToto(Mockito.any(Tutu.class)); 

    Titi testedObject = new Titi(); 
    testedObject.executeTiti(); 
} 
} 

그러나 진짜 방법은 항상 호출하고 RET = 5 매번 :(

내가 뭔가를 그리워합니까? I에 유래에 이것에 대해 많은 글을 읽고 모든 솔루션을 시도했지만 작동하지이기 때문에 내가 옳은 일을하고 있다고 생각해.

내가 마음에 junit4.11/powermock1.5.4/mockito1.9.5

답변

7
Toto toto = Mockito.spy(new Toto()); 

곰을 사용가이 스파이/토토이 줄을 만들 경우, 그리고마다 새로 생성 토토에 스텁. 그래서 당신은 전화 할 때 :

Titi testedObject = new Titi(); 
testedObject.executeTiti(); 

생성자 new Titi() 당신이 실행중인 때문에 this.toto.executeAction() 해당 호출이 항상 5


를 돌려 있도록 자체가 Mockito에 의해 영향을받지 토토의 새로운 인스턴스를 생성 나는 최고의 보조 항구 건설을 만드는 것입니다 좋아

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Titi.class) // stub the calling class Titi, not Toto! 
public class TitiTest { 
    @Test public void testExecuteTiti() { 
    Toto toto = Mockito.spy(new Toto()); 
    Mockito.doReturn(2).when(toto).executeToto(Mockito.any(Tutu.class)); 

    PowerMockito.whenNew(Toto.class).withAnyArguments().thenReturn(toto); 

    Titi testedObject = new Titi(); 
    testedObject.executeTiti(); 
    } 
} 

그러나 옵션 : PowerMockito, 당신은 stubbing Toto's constructor의 옵션이 할 테스트를 위해 티티에 대한 ctor에, :

public Titi(){ 
    this.toto = new Toto();  
} 

/** For testing only. Uses the passed Toto instance instead of a new one. */ 
Titi(Toto toto){ 
    this.toto = toto; 
} 

만이 같은 테스트를 조정할 필요

@Test public void testExecuteTiti(){ 
    Toto toto = Mockito.spy(new Toto()); 
    Mockito.doReturn(2).when(toto).executeToto(Mockito.any(Tutu.class)); 

    Titi testedObject = new Titi(toto); 
    testedObject.executeTiti(); 
} 
+0

안녕하세요, 도움 주셔서 감사합니다, 내 질문을 마침내 좋은 인스턴스와 그 작업을 전달하기 위해 생성자를 변경합니다. 난 그냥 다른 코드가 있기 때문에 다른 솔루션이 있는지 알고 싶지 테스트 및 나는 기존 코드를 터치하고 싶지 않아하지만, 나는 당신과 동의,이 경우에는 선택의 여지가 :) 감사합니다 –

+0

나는 생각합니다 레거시 코드의 빠른 리팩터링은 테스트를 더 쉽게할만한 가치가 있지만 프로덕션 코드를 변경하지 않고도 대답으로 PowerMockito 솔루션을 추구 할 수 있습니다. PowerMockito 코드를 조정해야 할 수도 있습니다. 그것을 가진 나의 경험은 한정되어있다. 행운을 빕니다! –

0

당신이없는 것 같다 무엇이 토토 클래스에 대한 당신의 스파이가 있다는 사실이다 Titi 클래스에서 실제로 사용되지 않습니다.

내가 귀하의 경우에서하는 것은

1) 생성자의 종속성으로 토토를 허용하도록 티티 클래스를 리팩토링이다.

public class Titi{ 
    private Toto toto; 

    public Titi(){ 
    this.toto = new Toto();  
    } 

    public void executeTiti(){ 
     //do some stuff 
     Tutu tutu = new Tutu(); 
     int ret = getToto().executeToto(tutu); 
     //do some stuff 
    } 

    //package private - used for overriding via spying 
    Toto getToto() { 
     return toto; 
    } 
} 

@RunWith(MockitoJUnitRunner.class) 
public class TitiTest { 

@Test 
public void testExecuteTiti(){ 
    Toto toto = Mockito.mock(Toto.class); 
    when(toto.executeToto(Mockito.any(Tutu.class)).thenReturn(2); 

    Titi testedObject = new Titi(); 
    testedObject = spy(testedObject); 
    doReturn(toto).when(testedObject).getToto(); 

    testedObject.executeTiti(); 
} 
} 
+0

예, 이전 답변에서 말한 것처럼 생성자를 변경할 선택이 없습니다. 도와 줘서 고마워. :) –

0

여기 (당신의 단위 테스트에서 모의을 사용하여 거기에 등)이 쉽게 토토와 티티를 만들 수 있습니다 그 방법은

2) 옵션 1을 사용하여 다음을 수행 할 수있는 문제를 벗어나면 공동 작업자를 주입하지 않는 클래스를 테스트하기 위해 한 줄 방법이나 공장 도우미 메서드 사용에 대해 설명하는 문서 https://code.google.com/p/mockito/wiki/MockingObjectCreation