0

特定のデータが HTTP に存在することを前提条件とする JUnit vs Spring MVC テスト ケースを実行する必要がありますSession。最も重要なのは、session-scoped Bean を配線できないことです。アクセスする必要がありますhttpServletContext.getSession()

コードを示す前に、説明させてください。テストする必要があるコントローラーは、特定のデータがセッションに保存されていることを前提としています。それ以外の場合は、例外がスローされます。そのコントローラーはセッションなしで呼び出されることはなく、セッションは常にログイン時にアプリケーション データで初期化されるため、これは現時点では正しい動作です。そして明らかに、コントローラーはセキュリティ下にあります。

私のテストでは、要求パラメーターに従って、このコントローラーがリダイレクトまたは 404 not found を返すかどうかをテストする必要があります。

次のようなテストケースを構築することを考えました

@Autowired
private HttpServletRequest httpServletRequest;

@Autowired
private ModuleManager moduleManager;

@Autowired
private WebApplicationContext webApplicationContext;

private MenuItem rootMenu;

private MockMvc mockMvc;


@Before
public void setUp() throws Exception
{

    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
                             // No asserzioni
                             .build();

    rootMenu = moduleManager.getRootMenu()
                            .clone();
    httpServletRequest.getSession()
                      .setAttribute(MenuItem.SESSION_KEY, rootMenu);

    assertNotNull(rootMenu.getDescendant(existingSelectedMenu));
    assertNull(rootMenu.getDescendant(notExistingMenu));

}

@Test
public void testNavigate() throws Exception
{

    mockMvc.perform(get("/common/navigate?target=" + existingSelectedMenu))
           .andExpect(status().is3xxRedirection());

    assertNotSelected(rootMenu, existingSelectedMenu);

    mockMvc.perform(get("/common/navigate?target=" + notExistingMenu))
           .andExpect(status().is4xxClientError());

}

コードの一部は本当に自明です。とにかく/common/navigate、セッションに保存した値を使用することを期待しています。このような

@RequestMapping(value = "/common/navigate",
        method = RequestMethod.GET)
public String navigate(@RequestParam("target") String target) throws NotFoundException
{

    MenuItem rootMenu = (MenuItem) httpServletRequest.getSession()
                                               .getAttribute(MenuItem.SESSION_KEY);
    if (rootMenu == null)
        throw new RuntimeException("Menu not found in session"); //Never happens

    MenuItem menuItem = rootMenu.getAndSelect(target);
    if (menuItem == null)
        throw new NotFoundException(MenuItem.class, target); //Expected

    return "redirect:" + menuItem.getUrl();
}

今推測します。コードを実行するとどうなりますか?

セッションでメニューオブジェクトが見つからないため、コメントした行でRuntimeExceptionがスローされます

明らかに、質問は今では暗黙的ですが、それでも書きます: テスト対象のコントローラーが前提条件として使用できるように、Session オブジェクトにデータを挿入するにはどうすればよいでしょうか?

4

1 に答える 1

0

今、自分で解決策を見つけました。

問題は、セッション自体もモックする必要があることです。Spring は、MockHttpSessionこのトリックを実行するクラスを提供します。すべての事前条件を事前に入力できますが、モックがセッションを (モックされた) サーブレット コンテキストに接続できるように、すべてのリクエストに渡す必要があります。MockMvc

次のコードはセッションを初期化します

    mockHttpSession = new MockHttpSession(webApplicationContext.getServletContext());

    mockHttpSession.setAttribute(MenuItem.SESSION_KEY, rootMenu);

以下は、それに接続されたモックセッションでリクエストを実行します

mockMvc.perform(get("/common/navigate?target=" + existingSelectedMenu).session(mockHttpSession))
           .andExpect(status().is3xxRedirection());
于 2015-08-21T12:54:43.487 に答える