Webアプリ開発エンジニアのための技術情報サイト「テックスコア」

5.3. testメソッド

テストするFilterはtestメソッドで指定します。

 
13: public void testEncode() throws ServletException, IOException
14: {
15:     EncodeFilter filter = new EncodeFilter();
16:     config.setInitParameter("encoding",ENCODING );
17:     filter.init(config);
18:     filter.doFilter(request, response, filterChain);
19:   assertEquals(ENCODING,request.getCharcterEncoding());   
20: }

15行目でテスト対象のフィルターのインスタンスを作成しています。

16行目でフィルターの設定を行っています。フィルターの設定はconfig暗黙オブジェクトを使用します。configオブジェクトはFilterConfigをラップするFilterConfigWrapperのインスタンスです。configクラスのsetInitParameterメソッドを実行するのは、web.xmlに以下のように記述した場合と同じ効果があります。設定を反映させるには、filterのinitメソッドを実行します。

<filter>
  <filter-name>Encoding</filter-name>
  <filter-class>EncodingFilter</filter-class>
  <init-param>
    <param-name>encoding</param-name>
    <param-value>EUC-JP</param-value>
  &lt/init-param>
&lt/filter> 

18行目で作成したFilterのdoFilterメソッドを実行しています。doGetメソッドが引数に取っているrequest、response、filterChainはsetUp()、testXXX()、tearDown()メソッド内で使用できるFilterTestCaseの暗黙オブジェクトです。サーブレットと同様、beginメソッドで設定したWebRequestの設定は、request暗黙オブジェクトに引き継がれます。doFilterメソッド実行により得られる、HTTPレスポンスはreponse暗黙オブジェクトに設定されます。response暗黙オブジェクトの内容はendXXX()メソッドの引数のWebResponseに引き継がれます。

最後に、ただしく文字コードが変換されているか、assertメソッドを使用して確認しています。

5.4. filterChain

実際の運用では、複数のフィルターが適用される場合もあります。被テストフィルターの後に、別のフィルターを実行し、そのレスポンスを確認したい場合は、filterChain暗黙オブジェクトを使用せずに、クラス内で定義したFilterChainオブジェクトを使用する方法があります。

例えば、以下のように、各ページにヘッダーを追加するフィルタがあったとします。

 1:public class SampleFilter implements Filter
 2:{
 3:
 4:   private FilterConfig config;
 5:
 6:
 7:   public void init(FilterConfig theConfig) throws ServletException
 8:   {
 9:       this.config = theConfig;
10:   }
11:
12:
13:    public void doFilter(ServletRequest theRequest,
14:        ServletResponse theResponse, FilterChain theChain)
15:        throws IOException, ServletException
16:    {
17:        OutputStream out = theResponse.getOutputStream();
18:        addHeader(out);
19:        org.apache.cactus.util.GenericResponseWrapper wrapper
20:         =new org.apache.cactus.util.GenericResponseWrapper((javax.servlet.http.HttpServletResponse) theResponse);
21:        theChain.doFilter(theRequest, wrapper);
22:        out.write(out.getData());
23:        out.close();
24:    }
25:
26:    protected void addHeader(OutputStream theOutputStream)
27:        throws IOException
28:    {
29:        String header = this.config.getInitParameter("header");
30:
31:        if (header != null) {
32:            theOutputStream.write(header.getBytes());
33:        }
34:    }
35:	
36:    public void destroy()
37:    {
38:    }
39:
40: }

SampleFilterはFilterConfigに設定されているヘッダーを各ページに追加するフィルターです。19、20行目でGenericResponseWrapperを導入しています。既に他のサーブレットで確定されているresponseに情報を書き足すことができないからために、ラッパークラスを導入しています。ここでは詳しく説明しません。

このフィルターのテストクラスは以下のようになります。

 1:public class TestSampleFilter {
 2: ...
 3:public void testAddHeader() throws ServletException, IOException
 4:  {
 5:    SampleFilter filter = new SampleFilter();
 6:    config.setInitParameter("header", "<h1>header</h1>");
 7:    filter.init(config);
 8:
 9:    FilterChain mockFilterChain = new TestFilterChain();
10:
11:    filter.doFilter(request, response, mockFilterChain);
12:  }
13:
14: public void endAddHeader(WebResponse theResponse)
15:  {
16:     assertEquals("<h1>header</h1><p>some content</p>",
17:        theResponse.getText());
18:  }
19:
20:    private class TestFilterChain implements FilterChain{
21:        public void doFilter(ServletRequest theRequest,
22:            ServletResponse theResponse) throws IOException, ServletException
23:        {
24:            PrintWriter writer = theResponse.getWriter();
25:            writer.print("<p>some content</p>");
26:            writer.close();
27:        }
28:        public void init(FilterConfig theConfig)
29:        {
30:        }
31:        public void destroy()
32:        {
33:        }
34:    }
35:
36:}

9行目で、テスト用に定義したFilterChainのインスタンスを作成しています。20-32行目にそのFilterChainを定義しています。FilterChainのdoFilterメソッドに、SampleFilterの処理を行った後に適用するFilterやServletの処理を記述します。例えば、SampleFilterHTTPレスポンスに指定されたヘッダーを付け足すフィルターです。"<p>some content</p>"という文字列を単純に返すサーブレットに適用すると、正しく実装されていたら"(ヘッダー)<p>some content</p>"という文字列が返されるはずです。これを確認するために、doFilterメソッドには、サーブレットの「"<p>some content</p>"という文字列を単純に返す」処理をそのまま記述しています。

11行目でSampleFilterのdoFilterメソッドを実行しています。引数で与えられたFilterChainオブジェクトはTestFilterChainのインスタンスです。これにより、Filterではまず、addHeaderメソッドが実行され、その後に"<p>some content</p>"を出力するFilterChainのdoFilterメソッドが実行されることになります。

最後に、14-19行目のendメソッドでResponseの評価を行います。

(実習課題1)

サーブレット6章実習課題2で作成したフィルターを、ブラウザーがIEだったら、(自分で作成したHTMLの)エラーページを表示するように変更しなさい。変更したフィルターのテストクラスを作成しなさい。



前のページへ TECHSCOREのTOPページへ 次のページへ
TECHSCORE PR
PR
PR
PR
PR
PR

techscore(トップページへ)
TECHSCORE書店
TECHSCOREトップページJavaSQLXMLリッチクライアントモデリングセマンティックWebその他技術Tuigwaa