Насмешливый приватный метод void дает AssertionError

1

Я создаю тестовые примеры с использованием Powermock для веб-службы в Джерси, и я пытаюсь высмеять вызовы функций базы данных, особенно для вызовов PUT и POST. Однако у меня возникают проблемы с тем, чтобы это работало.

Вот что выглядит один из вызовов веб-службы:

@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, null, "test_software", null, null, null, 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, null, null, "23", null]): expected: 1, actual: 0

Сделав немного больше копания, я обнаружил, что причина, скорее всего, связана с тем, как PowerMock сравнивает массивы String. Поэтому я также попытался использовать более общий подход, поскольку функция возвращает void в любом случае, используя EasyMock.anyString() и EasyMock.isA(String[].class) вместо двух аргументов, но это приводит к исключению NullPointerException вместо. Вот первые несколько строк этой stacktrace:

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)

Как правильно исправить этот частный метод void, чтобы избежать вызовов базы данных во время моего тестирования?

Теги:
unit-testing
powermock

1 ответ

1
Лучший ответ

После того, как я expectPrivate этот тест и документы несколько раз, я обнаружил, что вызов 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;
    }
});

Это также позволило мне сравнить с массивом, что функция, называемая так, как я изначально хотел, определял функцию, используя общие типы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню