2017-07-19 33 views
-1

我正在嘗試測試下面的ClientDetails類,並試圖同時學習JUnit和Mockito。如何正確使用Mockito模擬對象

// this is the class I'm trying to test 
public class ClientDetails { 

    @Autowired private IApplicantService<Applicant> applicantService; 
    @Autowired private ClientDetailsHelpers helpers; 

    public FullClientDetails getClientDetails(String businessId, boolean isNewClient) { 

     FullClientDetails fcd = new FullClientDetails(); 

     ClientParams params = new ClientParams(); 
     params.setBusinessId(businessId); 

     ApplicantId ai = applicantService.retrieveApplicantIdFromBusinessId(params); 
     Long applicantId = ai.getApplicantId(); 
     params.setApplicantId(applicantId); 

     Applicant applicant = applicantService.retrieveApplicantDetailsByHerdNumber(params); 
     helpers.validateRetrievedApplicant(applicant, isNewClient, businessId); 

     fcd.setApplicant(applicant); 
     // more method calls that get and assign objects to the fcd object 

     return fcd; 
    } 


} 

// ClientDetailsHelpers.java method that throws exception 
public void validateRetrievedApplicant(Applicant applicant, boolean isNewClient, String businessId) { 
    if (applicant.getApplicantId() == null && !isNewClient) { 
     throw new ValidationSearchException(businessId); 
    } 
} 

// test class 
@RunWith(MockitoJUnitRunner.class) 
public class ClientDetailsTest { 

    private final static String BUSINESS_ID = "A1234567"; 
    private final static Long APPLICANT_ID = null; 

    @InjectMocks 
    ClientDetails clientDetails; 

    @Mock ApplicantServiceImpl applicantService; 
    @Mock ClientDetailsHelpers helpers; 

    private ApplicantParams params; 
    private Applicant applicantWithInvalidId = new Applicant(); 

    ApplicantId applicantId = new ApplicantId(APPLICANT_ID, BUSINESS_ID); 

    @Before 
    public void before(){ 
     applicantWithInvalidId.setApplicantId(null); 
    } 

    @Test(expected = ValidationSearchException.class) 
    public void testGetFullApplicationDetails(){ 
     when(applicantService.retrieveApplicantIdFromBusinessId(Mockito.any(ApplicantParams.class))).thenReturn(applicantId); 
     when(applicantService.retrieveApplicantDetailsByHerdNumber(Mockito.any(ApplicantParams.class))).thenReturn(applicantWithInvalidId); 
     FullClientDetails fcd = clientDetails.getFullClientDetails(BUSINESS_ID , false); 
    } 
} 

在我的測試類,我創建了一些模擬對象,包括ApplicantId對象返回時applicantServiceretrieveApplicantIdFromBusinessId()被調用,並且申請人對象與申請者標識屬性設置爲空以便返回時申請者服務retrieveApplicantDetailsByHerdNumber()被調用。

函數ClientDetailsHelpervalidateRetrievedApplicant()應拋出異常,如果申請人getApplicantId()返回空,如果布爾isNewClient設置爲false,但它似乎並沒有在測試中發生的事情,它會拋出也不例外和@Test失敗。

我最好的猜測是,我沒有使用時()。thenReturn()正確回到我所創建的申請人和ApplicantId對象,而是另一個申請人對象獲得通過,以validateRetrievedApplicant(),返回和applicantId 0,當它到達驗證方法。

有什麼建議嗎?謝謝!

+1

不僅JUnit和Mockito。與Spring一起。 Imho:這聽起來有點像讓自己負擔過重。換句話說:不要一次做三件複雜的事情。當Mockito對你而言是新手時,那麼你就可以使用基本的Mockito教程。然後,當您獲得*一些*經驗時,請繼續並將其應用於您的生產代碼。或者你認爲在同一時間學習「獨輪車」和「雜耍」*會是明智的嗎? – GhostCat

+0

謝謝@GhostCat。那麼,我已經得到這個代碼基礎來維護/開發,它沒有單元測試。我真的不知道如何進行單元測試,因此我認爲我會使用真實世界的場景進行學習。 – Shane

+1

我相信有些人可以在騎獨輪車的同時學習雜耍。但是對於我們其他人來說:放慢速度。爲了高效地進行「反覆試驗」 - 您需要在該領域的一些經驗。否則,你所有的「試驗」都會出現「錯誤」。 – GhostCat

回答

1

您的代碼沒有拋出異常,因爲您正在測試的代碼中沒有地方會拋出異常。我假設你的異常拋出ClientDetailsHelpers類,但你嘲笑這個類,所以它不會調用實際的代碼,因此不會拋出異常。

你需要考慮你想測試什麼。你想單獨測試ClientDetails類嗎?在這種情況下,您不必擔心拋出的異常,因爲它不是該類的功能的一部分。

第二種選擇是,您希望進行更多的集成測試,您需要在實際的ClientDetailsHelpers類中進行測試,但爲了執行此操作,需要在測試中包含一些配置以確保此Bean可用到測試Spring上下文。您可以使用Spring4JunitRunner做到這一點,而不是一個的Mockito,然後在配置類,使用您的測試類@ContextConfiguration(MyConfig.class)註釋,其中的myconfig是相關的Spring配置類的ClientDetailsHelpers類組件掃描拉動。

+0

感謝@Plog,或許重新思考是爲了... – Shane