読者です 読者をやめる 読者になる 読者になる

(続) Cubby のテストを S2JUnit4 環境で行う

前回の続編。今、MockHttpServletRequest 諸々の InternalTestContextImpl で持っているモックについて悩み中です。。。

S2JUnit4 の InternalTestContextImpl では、S2FrameworkTestCase ではおなじみ (?) の MockHttpServletRequest などなどを ExternalContext に設定しているので、HttpServletRequest の型では暗黙オブジェクトとして問題なくバインディングされるのですが、MockHttpServletRequest ではバインディングされません。どういう事かというと、

@RunWith(Seasar2.class)
public class IndexActionTest {

    public HttpServletRequest request;
:

だと、request に InternalTestContextImpl で設定されている MockHttpServletRequestImpl がバインディングされるのですが、以下のようにするとバインディングされず null のままになります。

@RunWith(Seasar2.class)
public class IndexActionTest {

    public MockHttpServletRequest request; // null !!
:

実体としては、MockHttpServletRequestImpl なので、

@RunWith(Seasar2.class)
public class IndexActionTest {

    public HttpServletRequest request;
:
    @Test
    public void index() throws Exception {
        MockHttpServletRequest mock = (MockHttpServletRequest) request;
        mock.addParameter("hoge", "value");
: 

とすれば動くは動くのですが、どうにも。。。一つの解決策としては、以下のような Interface を定義し (簡単のため Request だけ)

public interface ActionTestContext extends TestContext {
    MockHttpServletRequest getRequest();
}

こんな実装クラスを用意し、

public class ActionTestContextImpl extends InternalTestContextImpl implements ActionTestContext {

    @Override
    public MockHttpServletRequest getRequest() {
        return super.request;
    }
}

s2junit4.dicon にこう設定する、と。

	<component name="context"
		class="unit.ActionTestContextImpl">
		<property name="ejb3Enabled">false</property>
	</component>

すると、

    ActionTestContext ctx;

    @Test
    public void index() throws Exception {

        ctx.getRequest().addParameter("hoge", "value");
:

こんな感じでかける、と。ただこれだと、S2JUnit4 のドキュメントにある書き方と違うやり方になるので、混乱しそうな気配があり、いまいちのような気も。。。もう少し悩んでみます。このようなケースでは、こうしている、といった定番のやり方があれば知りたい所です。