2014-09-24 113 views
1

我正在使用Powermock为泽西Web服务构建测试用例,我试图模拟数据库函数调用,专门用于PUT和POST调用。但是,我遇到问题需要解决。嘲笑私有无效方法给出AssertionError

这里是Web服务调用的一个样子:

@Path("/v1.0.0") 
public class WebService { 

    @POST 
    @Path("application") 
    @Consumes(MediaType.APPLICATION_JSON) 
    public Response createApplication(@QueryParam("callback") String callbackFunction, String body) 
      throws NamingException, SQLException, IllegalStateException, CacheException, UnknownHostException, 
      IOException { 
     String query = "exec spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"; 
     String[] params = new String[16]; 
     JSONObject json = (JSONObject) JSONValue.parse(body); 
     params[0] = json.get("name").toString(); 
     params[4] = json.get("software").toString(); 
     params[14] = json.get("customerid").toString(); 
     //Null checks for other params 

     runUpdateQuery(query, params); 

     return generateResponse(callbackFunction, null); 
    } 

    private void runUpdateQuery(String query, String[] queryParameters) { 
     //Handles running DB query 
    } 
} 

什么我测试的情况下目前的样子:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(WebService.class) 
@PowerMockIgnore({"javax.management.*"}) 
public class TestRestWebService { 

    @Test 
    public void test_createApplication_returns_http_success() throws Exception { 
     String query = "exec spInsertApplication ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?"; 
     String[] params = new String[16]; 
     params[0] = "test_app_name"; 
     params[4] = "test_software"; 
     params[14] = "23"; 

     WebService tested = createPartialMockAndInvokeDefaultConstructor(WebService.class, "runUpdateQuery"); 
     expectPrivate(tested, "runUpdateQuery", query, params).andAnswer(
       new IAnswer<Void>() { 
        @Override 
        public Void answer() throws Throwable { 
         return null; 
        } 
       }); 
     replay(tested); 

     String JSONString = "{\"name\":\"test_service_name\",\"software\":\"test_software\",\"customerid\":\"23\"}"; 
     Response output = tested.createApplication("CALLBACK", JSONString); 
     verify(tested); 
     assertTrue(output.getStatus() == 200); 
    } 
} 

在运行时,这是给我一个AssertionError说:

意外的方法调用WebService.runUpdateQuery(“exec spInsertApplication?,?,?,? ,?,?,?,?,?,?,?,?,?, ?,?,?“,[”test_service_name“,null,null,”test_software“, null,null, ,null,null,null,null,“23”,null]):

WebService.runUpdateQuery(“exec spInsertApplication?,?,?, ?,?,?,?,?,?,? ,?,?,?,?,?,?“,[”test_service_name“,null, null,null,”test_software“,null,null,null,null,null,null, null, 23,null]):预计:1,实际:0

经过多一点挖掘后,我发现原因很可能与PowerMock如何比较字符串a rrays。所以我也试着用更通用的方法,因为函数返回void无效,通过使用EasyMock.anyString()EasyMock.isA(String[].class)来代替我的两个参数,但是这会导致NullPointerException。下面是堆栈跟踪的前几行:

java.lang.NullPointerException 
    at java.lang.Class.isAssignableFrom(Native Method) 
    at org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432) 
    at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934) 
    at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025) 
    at org.powermock.reflect.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948) 

我如何去正确地嘲讽这种私人无效的方法,以避免我的测试过程中调用数据库?

回答

1

通过这次测试和文档挖掘了几次后,我发现expectPrivate调用没有找到我的方法。因此,这里是我发现我可以指定功能:

expectPrivate(tested, WebService.class.getDeclaredMethod("runUpdateQuery", String.class, String[].class), 
     EasyMock.anyString(), EasyMock.aryEq(params)).andAnswer(new IAnswer<Void>() { 
    @Override 
    public Void answer() throws Throwable { 
     return null; 
    } 
}); 

这也让我做的阵列的比较调用函数像我本来想同时使用泛型类型定义的功能。