したがって、基本的に、リクエストのフィルターに設定した属性は、ClientSessionServiceImpl で読み取ることができません。これは、MockHttpServletRequest の別のインスタンスがそこに挿入されるためです。
RequestAttributes
これは、Springが に取り込まれるタイミングに関するタイミングの問題RequestContextHolder
です。RequestContextFilter
本番環境では、またはのいずれかを構成していると想定しますRequestContextListener
。
いずれにせよ、RequestContextFilter
テストのフィルタ チェーンの先頭に のインスタンスを手動で追加すると、問題が解決します。
mockMvc = MockMvcBuilders
.webAppContextSetup(this.wac)
.addFilters(new RequestContextFilter(), testFilterChain)
.build();
これが Spring Framework 4.2 のデフォルトの動作になることに注意してください: シミュレートするコードRequestContextFilter
は に直接実装されMockMvc
ます。詳細については、JIRA の問題SPR-13217を参照してください。
余談MockHttpServletRequest
ですが、 によって作成された の設定ServletTestExecutionListener
はサポートされていません。使用しMockMvc
ている場合は、RequestBuilders
.
ServletTestExecutionListener
ただし、手動で作成したモック リクエストを変更し、それを で再利用する具体的な必要がある場合はMockMvc
、プロジェクトに次のクラスを作成できます。
package org.springframework.test.web.servlet.request;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.springframework.http.HttpMethod;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* Patched version of {@link MockHttpServletRequestBuilder}.
*
* @author Sam Brannen
* @since 4.2
*/
public class PatchedMockHttpServletRequestBuilder extends MockHttpServletRequestBuilder {
public static MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables) {
return new PatchedMockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, urlVariables);
}
public PatchedMockHttpServletRequestBuilder(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) {
super(httpMethod, urlTemplate, urlVariables);
}
/**
* Create a {@link MockHttpServletRequest}.
* <p>If an instance of {@code MockHttpServletRequest} is available via
* the {@link RequestAttributes} bound to the current thread in
* {@link RequestContextHolder}, this method simply returns that instance.
* <p>Otherwise, this method creates a new {@code MockHttpServletRequest}
* based on the supplied {@link ServletContext}.
* <p>Can be overridden in subclasses.
* @see RequestContextHolder#getRequestAttributes()
* @see ServletRequestAttributes
*/
@Override
protected MockHttpServletRequest createServletRequest(ServletContext servletContext) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes) {
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
if (request instanceof MockHttpServletRequest) {
return (MockHttpServletRequest) request;
}
}
return new MockHttpServletRequest(servletContext);
}
}
注:パッケージに入っている必要があります。org.springframework.test.web.servlet.request
そうしないと、MockHttpServletRequestBuilder
必要な拡張ができません。
次に、 fromの代わりに fromget()
メソッドを使用すると、すべてが期待どおりに機能するはずです!PatchedMockHttpServletRequestBuilder
MockMvcRequestBuilders
明らかに、上記の例はを再実装 get()
していますが、当然post()
、 などに対しても同じことができます。
参考までに: 上記のパッチを適用したバージョンを最終的createServletRequest()
に Spring Framework 4.2.x にコミットする可能性があります (JIRA issue SPR-13211を参照)。
よろしく、
Sam ( Spring TestContext フレームワークの作成者)