Попытка проверить HttpServletResponseWrapper внутри ResponseHeaderFilter с MockHttpServletResponse - PullRequest
1 голос
/ 06 февраля 2012

Я пытаюсь выполнить модульное тестирование нижеприведенного ResponseHeaderFilter, но обнаружил, что этот модульный тест не пройден:

@Test
public void testDoFilterWithOmmissableInitParameters_ETag()
        throws IOException, ServletException {

    // Add allowableUserAgents initParameters
    MockFilterConfig filterConfig = new MockFilterConfig();
    filterConfig.addInitParameter("allowableUserAgents", "avaya");

    // Add allowableUserAgents initParameters
    filterConfig.addInitParameter(OMIT_KEY, OMIT_VALUE);

    // Set user-agent
    request.addHeader("user-agent", "avaya");
    response.addHeader("ETag", "someEtagHash");

    filter.init(filterConfig);
    filter.doFilter(request, response, chain);

    // THIS ASSERTION FAILS:
    assertThat((String)response.getHeader("ETag"), is(nullValue()));
}

В частности, метод setHeader (), когда я запускаю его в режиме отладки, НИКОГДА не вызывается:

            chain.doFilter(request,
                                new HttpServletResponseWrapper(response) {
                                    public void setHeader(String name, String value) {
                                        //if (!(name != null && omitHeaders.contains(name.toUpperCase()))) {
                                        if (name != null && omitHeaders.contains(name)) {
                                            super.setHeader(name, value);
                                        }
                                    }
                                });

Отладчик попадает в строку для нового HttpServletResponseWrapper (response), но фактически не выполняет метод setHeader.

вот весь класс целиком:

public class ResponseHeaderFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(ResponseHeaderFilter.class);

    Map<String, String> additionalHeaders = new HashMap<String, String>();

    Set<String> omitHeaders = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

    Set<String> allowableUserAgents = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

    boolean allowFromAllUserAgents = false;

    public void doFilter(final ServletRequest request,
                         final ServletResponse res,
                         final FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        String userAgent = ((HttpServletRequest) request).getHeader("user-agent");

        if (allowFromAllUserAgents
            || (userAgent != null && allowableUserAgents.contains(userAgent))
        ) {
            logger.debug("apply ResponseHeader rules for user agent [{}]", userAgent);
            for (Map.Entry<String, String> entry : additionalHeaders.entrySet()) {
                response.addHeader(entry.getKey(), entry.getValue());
            }

            chain.doFilter(request,
                                    new HttpServletResponseWrapper(response) {
                                        public void setHeader(String name, String value) {
                                            //if (!(name != null && omitHeaders.contains(name.toUpperCase()))) {
                                            if (name != null && omitHeaders.contains(name)) {
                                                super.setHeader(name, value);
                                            }
                                        }
                                    });
        } else {
            logger.debug("User agent [{}] is not an allowable agent for this filter", userAgent);
            chain.doFilter(request, res);
        }
    }

    /**
     * Called once during start-up
     *
     * @param filterConfig for Filter configuration
     */
    public void init(final FilterConfig filterConfig) {

        logger.info("*** ResponseHeaderFilter.init() ***");

        // set the provided HTTP response parameters
        for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) {
            String headerName = (String) e.nextElement();
            String headerValue = filterConfig.getInitParameter(headerName);

            // Add the list of allowable user-agents
            // cannot be null: if (headerName != null) {
                if (headerName.equalsIgnoreCase("allowableUserAgents")) {
                    // omit
                    parseToUpperCaseElements(headerValue, allowableUserAgents);
                    logger.debug("allowable user-agent's {}", allowableUserAgents);
                } else if (headerName.equalsIgnoreCase("allowFromAllUserAgents")) {
                    allowFromAllUserAgents = Boolean.parseBoolean(headerValue);
                    logger.debug("allowFromAllUserAgents {}", allowFromAllUserAgents);
                } else if (headerName.equalsIgnoreCase("omit")) {
                    parseToUpperCaseElements(headerValue, omitHeaders);
                    logger.debug("Omit headers {}", omitHeaders);
                } else {
                    additionalHeaders.put(headerName, headerValue);
                    logger.debug("adding header [{}] with value [{}]", headerName, headerValue);
                }
            //}
        }
    }

    protected final void parseToUpperCaseElements(final String str, final Set<String> elementKeys) {
        String[] words = str.split(",");
        for (String s : words) {
            elementKeys.add(s.trim().toUpperCase());
        }
    }

    public void destroy() {
        logger.debug("destroy");
    }
}

Thisфильтр действительно работает при запуске и удаляет заголовок ETag, но когда я пытаюсь использовать Cobertura для покрытия кода, этот метод не тестируется.

1 Ответ

0 голосов
/ 06 февраля 2012

На самом деле код, который вы тестируете ResponseHeaderFilter добавляет или регистрирует только анонимный HttpServletResponseWrapper в FilterChain:

chain.doFilter(request, new HttpServletResponseWrapper(response) {
    public void setHeader(String name, String value) { ... }
});

И FilterChain выполняется самим контейнером. Ваш тестовый код ничего не делает, кроме передачи ссылки FilterChain.

Я не знаю реального типа вашего FilterChain в вашем тесте, но вместо того, чтобы утверждать, что тег был удален (assertThat((String)response.getHeader("ETag"), is(nullValue()));), я бы разделил ваш тест на два разных теста.

  1. Замените анонимный HttpServletResponseWrapper полным типом, который можно назвать EtagRemoverHttpServletResponseWrapper, и проведите модульный тест, который фактически подтвердит, что в wrapper.setHeader(...) его заголовок etag опущен.

  2. Первый на вашем ResponseHeaderFilter, который будет утверждать, что chain содержит ссылку типа ETagRemoverHttpServletResponseWrapper

Надеюсь, это поможет.

...