2012-02-06 82 views
1
一個ResponseHeaderFilter內

我試圖單元測試下面ResponseHeaderFilter但發現這個單元測試失敗:嘗試測試HttpServletResponseWrapper與MockHttpServletResponse

@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(響應)的線,但實際上並沒有執行該方法的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"); 
    } 
} 

運行時,此過濾器的實際工作並執行刪除ETag頭,但是當我試圖使用的Cobertura代碼覆蓋,該方法沒有進行測試。

回答

0

其實你正在測試ResponseHeaderFilter代碼只會增加或註冊的FilterChain匿名HttpServletResponseWrapper

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

而且FilterChain由容器本身執行。你的測試代碼除了傳遞一個FilterChain引用外什麼也不做。

我不知道您的測試中您的FilterChain的實際類型,但不是斷言標籤已被刪除(assertThat((String)response.getHeader("ETag"), is(nullValue()));)我將在兩個不同的測試中分割您的測試。

  1. 由一個完整的類型,可以調用EtagRemoverHttpServletResponseWrapper和使一個單元測試,實際上將斷言上wrapper.setHeader(...)它ETag頭省略更換匿名HttpServletResponseWrapper

  2. 首先您ResponseHeaderFilter將斷言chain包含類型ETagRemoverHttpServletResponseWrapper

希望幫助的參考。