StrutsTestCase for JUnit v1.7

Now supporting Struts 1.1!

Struts 1.1をサポートしました!

Copyright (C) 2002 Deryl Seale


Questions? Comments? Please mail me at deryl@acm.org, or take a short survey.

What is it?

これは何?

StrutsTestCase for JUnit is an extension of the standard JUnit TestCase class that provides facilities for testing code based on the Struts framework. StrutsTestCase provides both a Mock Object approach and a Cactus approach to actually run the Struts ActionServlet, allowing you to test your Struts code with or without a running servlet engine. Because StrutsTestCase uses the ActionServlet controller to test your code, you can test not only the implementation of your Action objects, but also your mappings, form beans, and forwards declarations. And because StrutsTestCase already provides validation methods, it's quick and easy to write unit test cases.

StrutsTestCase for JUnit は標準のJUnit TestCaseクラスの拡張であり、 Strutsフレームワークベースでの便利なテスト用コードを提供します。 StrutsTestCaseは、擬似オブジェクト(Mock Object)アプローチCactus アプローチ の両方を、 実際に実行するStruts ActionServletに提供します。 なぜらなら、StrutsTestCaseはActionServletコントローラを使って、コードをテストします。 Actionオブジェクトだけでなく、マッピング、フォームビーンズとフォワードの定義もテストできます。 そして、StrutsTestCaseは、既に確認用メソッドを提供しています。それは、ユニットテストケースにおいて、 クイックで簡単です。



StrutsTestCase is compliant with both the Java Servlet 2.2 and 2.3 specifications, and supports Struts 1.1 and 1.0.2, and Cactus 1.2.

StrutsTestCaseは、Java Servlet2.2とServlet2.3仕様に従っており、Struts1.1とStruts1.0.2、そしてCactus1.2をサポートしています。



Where does it live?

何処にそれはあるの?

StrutsTestCase for JUnit is hosted at SourceForge. You can find the latest and greatest release of StrutsTestCase here. Javadocs for all of the StrutsTestCase classes can be found here, and there is also a list of frequently asked questions.

StrutsTestCase for JUnit はSourceForgeにあります。 最新のStrutsTestCaseのリリースは ここで見つける事ができます。 StrutsTestCaseのクラスの全てのJavadocは、ここで、見つける事ができます. また、よくある質問への答えのリストがあります。



Mock Testing vs. In-Container Testing

擬似テスト VS コンテナ内テスト

There are two popular approaches to testing server-side classes: mock objects, which test classes by simulating the server container, and in-container testing, which tests classes running in the actual server container. StrutsTestCase for JUnit allows you to use either approach, with very minimal impact on your actual unit test code. In fact, because the StrutsTestCase setup and validation methods are exactly the same for both approaches, choosing one approach over the other simply effects which base class you use!

サーバサイドのクラスをテストする2つの有名なアプローチがあります。 擬似オブジェクトは、サーバコンテナをシミュレートしてクラスをテストします。 そして、コンテナ内テストは、実際のサーバコンテナを実行してクラスをテストします。 StrutsTestCase for JUnitは、実際のユニットテストコードに最小の影響で、 いずれかのアプローチを提供します。 実際には、StrutsTestCaseセットアップおよびバリデーションメソッドは、両方のアプローチに対して、 正確に同じであるので、1つのアプローチを単に選べば、もう一方のアプローチへは、 その基底クラスを換えることで行えます。

StrutsTestCase for JUnit provides two base classes, both of which are extensions of the standard JUnit TestCase. MockStrutsTestCase uses a set of HttpServlet mock objects to simulate the container environment without requiring a running servlet engine. CactusStrutsTestCase uses the Cactus testing framework to test Struts classes in the actual server container, allowing for a testing environment more in line with the actual deployment environment.

StrutsTestCase for JUnitは、2つのベースクラスを提供します。それぞれは、JUnit TestCaseの標準拡張です。 MockStrutsTestCase は、サーブレットエンジンの実行を必要としない、コンテナ環境をシミュレートする HttpServlet擬似オブジェクトのセットを使います。 CactusStrutsTestCase は実際のデプロイ環境に従って、より多くのテスト環境を考慮し、 実際のサーバコンテナ内のStrutsのクラスをテストするために、 Cactus テスティングフレームワーク を使います。

Please note that while the following examples use the MockStrutsTestCase approach, you could choose to use the Cactus approach by simply subclassing from CactusStrutsTestCase without changing another line of code!

注意下記の例は、MockStrutsTestCaseアプローチを使っています、 単にサブクラスをCactusStrutsCaseにする事で、他の行を変える事なく、Cactusアプローチを選択出来ます。

How does it work?

どのように動作するの?

Please note that there are many more methods in the StrutsTestCase library than are illustrated here -- check out the javadocs for a complete picture of what you can do with StrutsTestCase!

Using the popular cookbook approach, let's consider the following code snippet:

注意ここで例示されるよりもさらに多くのメソッドがStrutsTestCaseライブラリにはあります。 -- あなたがStrutsTestCaseで出来る完全な描写であるjavadocsをチェックしてください!

有名なクックブックアプローチを使って、下記のコードの抜粋を検討してみましょう。

public class LoginAction extends Action {

    public ActionForward perform(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) 
    {

        String username = ((LoginForm) form).getUsername();
        String password = ((LoginForm) form).getPassword();

        ActionErrors errors = new ActionErrors();

        if ((!username.equals("deryl")) || (!password.equals("radar")))
            errors.add("password",new ActionError("error.password.mismatch"));

        if (!errors.empty()) {
            saveErrors(request,errors);
            return mapping.findForward("login");
        }
	
	// store authentication info on the session
        HttpSession session = request.getSession();
        session.setAttribute("authentication", username);

        // Forward control to the specified success URI
        return mapping.findForward("success");

    }

So, what are we doing here? Well, we receive an ActionForm bean which should contain login information. First, we try to get the username and password information, and then check to see if it is valid. If there is a mismatch in the username or password values, we then create an ActionError message with a key to a message catalogue somewhere, and then try to forward to the login screen so we can log in again. If the username and password match, however, we store some authentication information in the session, and we try to forward to the next page.

そうすると、ここで、何を行っていますか? さて、私達は、ログイン情報を含んでいるはずのActionFormビーンを受け取ります。 はじめに、ユーザ名とパスワードの情報の入手を試みます。 そして、それが正しいかチェックします。 もし、それらユーザ名とパスワードの値がミスマッチなら、 メッセージカタログのキーをもったActionErrorメッセージを何処かに生成します。 そして、再びログインできるように、ログインスクリーンに遷移します。 もし、ユーザ名とパスワードがマッチしたら、 その時は、セッションに認証情報を格納します。そして、次のページに遷移します。


There are several things we can test here:

ここでいくつかの事がテスト出来ます。


StrutsTestCase gives you the ability to test all of these conditions within the familiar JUnit framework. All of the Struts setup -- which really amounts to starting up the ActionServlet -- is taken care of for you.

StrutsTestCaseは、よく知られているJUnitフレームワーク内のこれらの条件を全てテストする機能を提供します。 Strutsセットアップは、実際にどれが ActionServletの開始になるのかを、全て行ってくれます。


So, how do we actually do it? Let's start by creating an empty test case, which we extend from the base StrutsTestCase class:

そうすると、実際には、どのようにそれを実現するのでしょう? ベースとなるStrutsTestCaseクラスから拡張した、空のテストケースの作成よりスタートしましょう:


public class TestLoginAction extends MockStrutsTestCase {

    public void setUp() { super.setUp(); }

    public void tearDown() { super.tearDown(); }

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {}
}
NOTE: If you choose to override the setUp() method, youmust explicitly call super.setUp(). This method performs some important initialization routines, and StrutsTestCase will not work if it is not called.

注意:もし、setUp()メソッドをオーバーライドする選択をしたなら、 super.setUp()を明示的に呼ばなければなりません。 このメソッドは、いくつかの重要な初期化ルーチンを事項します。 そして、もしそれが呼ばれない場合、StrutsTestCaseは動作しません。



The first thing we need to do is to tell Struts which mapping to use in this test. To do so, we specify a path that is associated with a Struts mapping; this is the same mechanism that the Struts tag library method uses.

最初に行う必要があることは、このテストで、どのマッピングを使用するべきであるかStrutsに伝える事です。 そうするために、Strutsマッピングに関係しているパスを指定します。これは、Strutsタグライブラリが使用する方法と同じメカニズムです。


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
    }
}

Next we need to pass form bean properties, which we send via the request object (again, just as Struts does):

次は、再びStrutsに、リクエストオブジェクトを経由して、Beanプロパティを渡す必要があります


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
       addRequestParameter("username","deryl");
       addRequestParameter("password","radar");
    }
}

Finally, we need to get the Action to do its thing, which just involves executing the actionPerform method:

最後に、アクションを実行させる必要があります。それは、actionPerformメソッドを実行させる事を含みます。


NOTE: By default, the Struts ActionServlet will look for the file WEB-INF/struts-config.xml, so you must place the directory that contains WEB-INF in your CLASSPATH. If you would like to use an alternate configuration file, please see the setConfigFile() method for details on how this file is located.

注意標準では、Struts ActionServletは、WEB-INF/struts-conifg.xmlを探すでしょう。 したがって、クラスパスに contains WEB-INFディレクトリを置かなくてはなりません。 もし、代わりのコンフィグレイションファイルを使用したい場合、 このファイルがどのように探し出されるかの詳細に関しては、 setConfigFile() を見てください。


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
       addRequestParameter("username","deryl");
       addRequestParameter("password","radar");
       actionPerform();
    }
}

That's all you have to do to get the ActionServlet to process your request, and if all goes well, then nothing will happen. But we're not done yet -- we still need to verify that everything happened as we expected it to. First, we want to make sure we got to the right page:

それは、ActionServletにリクエストを処理させるためにしなければならない、全てです。そして、全てがうまくいく場合、何もおこりません。 しかし、まだ終わっていはいません。 期待した、全ての場合が起こったことを確認する必要があります。 はじめに、正しいページに行き着いたことを確かめたいなら・・・


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
       addRequestParameter("username","deryl");
       addRequestParameter("password","radar");
       actionPerform();
       verifyForward("success");
    }
}

It's worth noting here that when you verify which page you ended up at, you can use the Struts forward mapping. You don't have to hard code filenames -- the StrutsTestCase framework takes care of this for you. Thus, if you were to change where "success" pointed to, your tests would still work correctly. All in the spirit of Struts.

それは、どのページで終了したかを確認する場合に、Strutsフォワードマッピングを使えることに注目してください。 ファイル名をハードコードしなくてもよいのです。StrutsTestCaseフレームワークがこれを行ってくれます。 したがって、もし“success”のポイントが変化しても、テストはまだ、正確に働くでしょう。Strutsの精神の全てです。


Next, we want to make sure that authentication information was stored properly:

次に、認証情報が適切に格納されたかを確かめたいなら・・


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
       addRequestParameter("username","deryl");
       addRequestParameter("password","radar");
       actionPerform();
       verifyForward("success");
       assertEquals("deryl",(String) getSession().getAttribute("authentication"));
    }
}

Here we're getting the session object from the request, and checking to see if it has the proper attribute and value. You could just as easily place an object on the session that your Action object expects to find. All of the servlet classes available in the StrutsTestCase base classes are fully functioning objects.

ここで、リクエストからセッションオブジェクトを得ており、 それが適切な属性と値をもっているかどうかチェックします。 セッション内から、あなたのアクションオブジェクトは、 オブジェクトを簡単に見つけられます。


Finally, we want to make sure that no ActionError messages were sent along. We can use a built in method to make sure of this condition:

最後に、ActionErrorメッセージがともに送られなかったことを確かめたいなら・・・
この条件では、組み込み機能を使う事ができます。


public class TestLoginAction extends MockStrutsTestCase {

    public TestLoginAction(String testName) { super(testName); }

    public void testSuccessfulLogin() {
       setRequestPathInfo("/login");
       addRequestParameter("username","deryl");
       addRequestParameter("password","radar");
       actionPerform();
       verifyForward("success");
       assertEquals("deryl",(String) getSession().getAttribute("authentication"));
       verifyNoActionErrors();
    }
}

So, now that we've written one test case, it's easy to write another. For example, we'd probably want to test the case where a user supplies incorrect login information. We'd write such a test case like the following:

以上で、1つのテストケースを書いたので、別のものを書くことは簡単です。 例えば、ユーザが正しくないログイン情報を提供する場合をテストしたいと思うでしょう。 そのときは、下記のようなテストケースを書けば良いでしょう。


public void testFailedLogin() {

    addRequestParameter("username","deryl");
    addRequestParameter("password","express");
    setRequestPathInfo("/login");
    actionPerform();
    verifyForward("login");
    verifyActionErrors(new String[] {"error.password.mismatch"});
    assertNull((String) getSession().getAttribute("authentication"));
}

Now, this looks quite similar to our first test case, except that we're passing incorrect information. Also, we're checking to make sure we used a different forward, namely one that takes us back to the login page, and that the authentication information is not on the session.

さて、これは正しくない情報を渡している以外は、 私たちの最初のテストケースによく似ているように見えます. また、異なるフォワードが使われたか、すなわち、 ログインページに戻ったか、そして、認証情報がセッションにないことを、確認しています.


We're also verifying that the correct error messages were sent. Note that we used the symbolic name, not the actual text. Because the verifyActionErrors() method takes a String array, we can verify more than one error message, and StrutsTestCase will make sure there is an exact match. If the test produced more error messages than we were expecting, it will fail; if it produced fewer, it will also fail. Only an exact match in name and number will pass.

正しいエラーメッセージが送られたことも確認しています. 私たちが実際のテキストではなく記号の名前を使用したことに注意してください. verifyActionErrors()メソッドがストリングの配列をとるので、 私たちは1つを越えるエラー・メッセージを確認することができます. また、StrutsTestCaseは、正確な適合があることを確かめるでしょう.


It's that easy! As you can see, StrutsTestCase not only tests the implementation of your Action objects, but also the mappings that execute them, the ActionForm beans that are passed as arguments, and the error messages and forward statements that result from execution. It's the whole enchilada!

それは簡単に見ることができます。StrutsTestCaseは、アクションオブジェクトのテストだけでなく、 マッピングの実行、引数が渡されたActionFormBean、エラーメッセージ、 実行結果によるフォワード文もテストできます。
これで、完璧です!


SourceForge Logo


Translated by Yukimitsu Kurozumi