2013-10-31 120 views
2

你好,我有一個方法,一個服務:嘲笑方法的Mockito不叫

@Service 
public class CaptchaServiceImpl implements CaptchaService { 

@Autowired 
private MessageSource messageSource; 

@Override 
public boolean processCaptcha(String requestedUrl, String challenge, String userResponse) { 

    ReCaptchaImpl reCaptcha = new ReCaptchaImpl(); 
    reCaptcha.setPrivateKey(messageSource.getMessage("reCaptcha.private.key", new Object[]{}, new Locale("pl", "PL"))); 
    ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(requestedUrl, challenge, userResponse); 

    return reCaptchaResponse.isValid(); 
} 

}

,我寫了這一個測試:

@RunWith(MockitoJUnitRunner.class) 
public class CaptchaServiceImplTest { 

private CaptchaService captchaService; 

@Mock 
private MessageSource messageSource; 

@Mock 
private ReCaptchaImpl reCaptcha; 

@Before 
public void init() { 
    captchaService = new CaptchaServiceImpl(); 
    ReflectionTestUtils.setField(captchaService, "messageSource", messageSource); 
} 

@Test 
public void shouldPassReCaptchaValidation() { 
    ReCaptchaTestResponse captchaResponse = new ReCaptchaTestResponse(true, "no errors"); 
    when(messageSource.getMessage("reCaptcha.private.key", new Object[]{}, new Locale("pl", "PL"))).thenReturn("reCaptcha.private.key"); 
    when(reCaptcha.checkAnswer(anyString(), anyString(), anyString())).thenReturn(captchaResponse); 

    boolean reCaptchaResponse = captchaService.processCaptcha("url", "challenger", "userResponse"); 

    assertThat(reCaptchaResponse, is(true)); 
} 

private class ReCaptchaTestResponse extends ReCaptchaResponse { 

    protected ReCaptchaTestResponse(boolean valid, String errorMessage) { 
     super(valid, errorMessage); 
    } 
} 

}

ReCaptchaResponse是受保護的類...

所以,當我跑我的測試我得到:

java.lang.AssertionError: 
Expected: is <true> 
got: <false> 

出於某種原因,我嘲笑方法checkAnswer永遠不會被調用,並再也沒有回到我的captchaResponse對象,我已經跑出去的想法,爲什麼。有人可以告訴我爲什麼會發生?也許我失去了一些東西:/

UPDATE:

所以我已經更新了我的CaptchaService:

@Autowired 
private ReCaptchaImpl reCaptcha; 

@Override 
public boolean processCaptcha(String requestedUrl, String challenge, String userResponse) { 
    reCaptcha.setPrivateKey(messageSource.getMessage("reCaptcha.private.key", new Object[]{}, new Locale("pl", "PL"))); 
    ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(requestedUrl, challenge, userResponse); 

    return reCaptchaResponse.isValid(); 
} 

,現在的測試是綠色的! :)謝謝

+0

您使用的是FEST嗎? 'assertThat(reCaptchaResponse,is(true));'看起來不正確 - 我_think_應該是'assertThat(reCaptchaResponse).isTrue();' –

+0

FEST表示什麼? –

+1

這是一個測試庫。 https://code.google.com/p/fest/ –

回答

7

這就是問題所在:

ReCaptchaImpl reCaptcha = new ReCaptchaImpl(); 

這只是創建一個新的實例 - 你的模擬沒有被使用的。請注意,你是如何不將任何東西傳遞給你的 - 你期望生產代碼如何使用它?

Mock對注入的依賴關係,甚至工廠返回的依賴關係都很好,可以讓工廠返回模擬給你 - 但是你只是調用構造函數。

可以使用PowerMock這一點,但我建議要麼重新設計,以避免需要模擬可言,或者允許地方注入的依賴。

+0

你說得對,我必須爲Spring配置一個ReCaptchaImpl bean。我認爲可能會有問題..剛剛發生日食。感謝您指出了這一點! –

+0

你應該加粗**重新設計**;) – Brice