2017-07-19 69 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