回答:
主に単体テストが開発の焦点になる前に開発されたため、JSPをテストする良い方法はないと思います。
Robert Martinは、数年前に、JSPコンパイラーをハッキングして、非コンテナーベースの単体テストを指示できるようにする記事を書きました。彼のアイデアは良かったが、TomCatの次のメジャーリリースでは壊れていた。あまりにも多くの魔法が起こっています。
「コードを追加しないでください。コードをテストする必要はありません」という考えに同意しません。明らかに、JSPにコードを入れるべきではありません。それにもかかわらず、複雑なUIには、有益な単体テストが可能な表示ロジックが含まれることがよくあります。
この例を考えてみましょう:
<c:choose>
<c:when test="${mydto.showAdminMenu}">
The admin menu....
</c:when>
<c:otherwise>
Something completely different
</c:otherwise>
</c:choose>
このコードはすでに十分に考慮されています。管理メニューを表示するかどうかを決定するロジックはビューにありません。それでも、JSPを単体テストする簡単な方法があれば、実際に必要な動作が表示されることを示すテストを作成できます。これにより、管理メニューが誤って表示されるページを変更することから保護できます。しないでください。
.jspファイルを.javaファイルにコンパイルするプログラム(使用しているアプリケーションサーバーで使用)が存在します。たとえば、sun / oracleバージョンのjspcです。
.jsp変換によって生成される.javaを取得したら(ビルドプロセスの一部としてこれを使用することを検討することもできます-最初のヒットでパフォーマンスを向上させるためにjspをプリコンパイルする)、それに対してテストを実行できますリクエストをモックし、レスポンスが期待どおりであることを確認します。
(例で編集:)
このための重要なメソッドは_jspService(HttpServletRequest, HttpServletResponse)
メソッドです。
ささいなhello world jsp:
<html>
<head>
<title>Hello world</title>
</head>
<body>
<h1>Hello world</h1>
Today is: <%= new java.util.Date().toString() %>
</body>
</html>
(「webapp」という名前のディレクトリと「out」ディレクトリ内にあるtest.jsp)コマンドを使用してコンパイルすると、という名前のjspc -v -d out -compile -uriroot webapp/ test.jsp
ファイルがoutディレクトリに配置されますtest_jsp.java
。このファイルには、他の構成設定もかなり含まれています:
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("<html>\n\t<head>\n\t\t<title>Hello world</title>\n\t</head>\n\t<body>\n\t
\t<h1>Hello world</h1>\n\t\tToday is: ");
out.print( new java.util.Date().toString() );
out.write("\n\t</body>\n</html>\n\n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
この時点で、JspWriterがwriteまたはprintで呼び出され、呼び出しの内容が予想どおりであることを確認するチェック。
つまり、理想的な世界では、jsp内にロジックはないはずです。そのようなロジックは、コントローラーまたは他の手法でテストされたtaglibにあります。
HTTPUnit |のようなHTTP単体テストフレームワークの使用を検討することもできます。http://httpunit.sourceforge.net/。
もう1つの重要な点は、アプリケーションの懸念を十分に分離することです。
たとえば、TDD(http://en.wikipedia.org/wiki/Test-driven_development)などの手法を使用して、テスト容易性のために型を設計します。
JSP内で消費されるタイプは、特定の単体テストでテストされます。これが不可能な場合は、ユーザー->ブラウザーの相互作用をシミュレートする必要があります(やはり、HTTPUnitまたは同様のツール)。