使用 Spring 进行 JUnit 测试

发布于 2024-12-06 00:50:51 字数 1857 浏览 4 评论 0原文

我正在尝试为 spring 控制器方法创建 junit 测试,但我不断收到以下错误

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, 
or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, 
your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:123)

我已经添加了它告诉我我需要的两件事(我已经分别尝试了每一项),目前我的 web.xml 包含

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
 </listener>

<filter> 
    <filter-name>requestContextFilter</filter-name> 
    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> 
</filter> 
    <filter-mapping> 
    <filter-name>requestContextFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping>

和该方法我正在尝试测试类似的东西

@Controller
@RemotingDestination
public class MyController {

public Response foo()
    {
//...
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession httpSession = attr.getRequest().getSession(true);
//...
}

,我的 junit 测试只是调用 myController.foo() 并检查响应。因此,我无法创建模拟对象来传递到方法中来解决此问题。

所以我想我的问题是,是否存在一些我尚未偶然发现的配置或技巧可以使此运行而无需重构我的控制器方法?

I am trying to create a junit test for a spring controller method but I keep receiving the following error

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, 
or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, 
your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:123)

I have added both the things it tells me I need (I've tried each one separately) and currently my web.xml contains

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
 </listener>

<filter> 
    <filter-name>requestContextFilter</filter-name> 
    <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class> 
</filter> 
    <filter-mapping> 
    <filter-name>requestContextFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping>

and the method I'm trying to test is something along the lines of

@Controller
@RemotingDestination
public class MyController {

public Response foo()
    {
//...
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpSession httpSession = attr.getRequest().getSession(true);
//...
}

and my junit test simply calls myController.foo() and checks the reponse. So I can't create a mock object to pass into the method to get around this issue.

So I suppose my question is, does there exist some configuration or trick that I have yet to stumble upon that will make this run without having to refactor my controller method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

悍妇囚夫 2024-12-13 00:50:51

错误信息非常清楚。不幸的是,您的代码需要进行一些重写。

首先,在测试您的控制器时,您(显然)不在网络请求中。这就是 RequestContextHolder.currentRequestAttributes() 不起作用的原因。但是您可以使用以下技术使您的测试通过并重构代码以使其更具可读性(假设您需要一个 HTTP 会话来从中获取一些实际属性):

public Response foo(@SessionAttribute("someSessionAttribute") int id)

这样 Spring MVC 将自动在 Web 请求中获取会话并加载 someSessionAttribute(甚至执行所需的转换)。但是当你测试控制器时,只需调用具有固定参数的方法即可。没有请求/会话基础设施代码。更加清晰(请注意,您提供的 foo 中的两行根本不需要)。

另一种解决方案是手动注册 RequestScope。请参阅此处的示例。这应该可以工作,而无需使用模拟请求和会话修改任何代码。

The error message is pretty clear. Unfortunately your code requires a bit of a rewrite.

First of all while testing your controller you (obviously) are not inside a web request. That's why RequestContextHolder.currentRequestAttributes() does not work. But you can make your test to pass and refactor the code to be much more readable using the following technique (assuming you need an HTTP session to get some actual attribute from it):

public Response foo(@SessionAttribute("someSessionAttribute") int id)

This way Spring MVC will automatically fetch the session and load someSessionAttribute when inside a web request (and even perform required conversion). But when you are testing the controller, just call the method with fixed parameter. No request/session infrastructure code. Much cleaner (note that the two lines in foo you've provided aren't needed at all).

The other solution is to register RequestScope manually. See example here. This should work without modifying any of your code with mocked request and session.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文