在JUnit测试中为数据库依赖创建模拟对象

时间:2015-03-10 12:32:45

标签: java junit mocking mockito junit4

我创建了一个JUnit测试,它使用数据库连接来获取一些数据,然后将结果与某些值进行比较以进行验证。 我知道我可以使用Mock Object概念来删除测试函数的数据库依赖性,但我不知道该怎么做。

这是我的测试类方法 -

ValidateTest.java

public void testValidateID() {
    Validate validateFields = new Validate();   
    MyID userID = readXmlAndReturnID("UserID.xml");
    boolean expectedResponse = true;
    boolean actualResponse = validateFields.validateSpecifiedID(myID);
    Assert.assertEquals(expectedResponse, actualResponse);
}

这是我使用数据库的实际类方法 -

Validate.java

public boolean validateSpecifiedID(MyID myID){
List<String> incomingList = myID.getuserID();
UserIDProgramHome userIDProgramHome = new UserIDProgramHome();

//this requires postgres database connectivity
idList = userIDProgramHome.findIDsByProgram(myID); 
    if(idList.get(0).equals(incomingList.get(0))){
        return true;
    }
    else{
        return false;
    }
}

2 个答案:

答案 0 :(得分:0)

您需要一种将模拟对象注入到测试类中的方法。您的validateSpecifiedID()方法的问题在于它在方法本身中创建了UserIDProgramHome的实例,当它看起来可能是您需要模拟的对象时。

一个常见的解决方案是重构代码,以便将这些类型的依赖项传递给类的构造函数。然后在测试中,您可以传递一个模拟对象,并验证被测试类的行为。

查看您的特定测试,我会考虑嘲笑两件事:您的MyID实例和传递给新UserIDProgramHome构造函数的Validate。您在测试中唯一关心的是该方法检查myID.getuserID()的结果,并根据userIDProgramHome.findIDsByProgram()的结果返回true或false。

答案 1 :(得分:0)

确切的解决方案取决于您用于测试的模拟库/库。使用JMockit,您可以按如下方式编写测试,将代码保留为:

@Test
public void testValidateID(@Mocked final UserIDProgramHome home) {
    Validate validateFields = new Validate();   
    MyID userID = readXmlAndReturnID("UserID.xml");
    final String firstIDValue = userID.getUserID().get(0);

    new Expectations() {{
        home.findIDsByProgram((MyID) any); result = firstIDValue;
    }};

    boolean idIsValid = validateFields.validateSpecifiedID(userID);

    assertTrue(idIsValid);
}

也可以使用Mockito + PowerMock编写同等测试。在任何一种情况下,都不需要对类Validate进行修改。