Java 如何使用JUnit4测试Spring';模拟请求下的el表达式?

Java 如何使用JUnit4测试Spring';模拟请求下的el表达式?,java,spring,junit4,easymock,Java,Spring,Junit4,Easymock,这就是我所拥有的,但Assert始终包含AsserationException: @Configuration public class Config @Bean public HttpServletRequest request(){ HttpServleRequest mock = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(mock.getParameter("test")).an

这就是我所拥有的,但Assert始终包含AsserationException:

@Configuration
public class Config
  @Bean
  public HttpServletRequest request(){
     HttpServleRequest mock = EasyMock.createMock(HttpServletRequest.class);
     EasyMock.expect(mock.getParameter("test")).andReturn("123").anyTimes();
     EasyMock.replay(mock);
     return mock;
  }

  @Bean
  MySerivce service(){
    return new MyService();
  }

  @Bean
  public ApplicationContextProvider context(){
    return new ApplicationContextProvider();
  }
}
这是服务
MyService.java

public class MyService{
  public void assertHasRequest(@Value("#{request}") HttpServletRequest request)){
    assert request != null;
  }
}
@RunWith(SpringJUnit4ClasssRunner.class)
@ContextConfiguration(classes=Config.class)
public class TestExpressions {

  @Autowired
  MyService service;

  @Test
  public void testService(){
    service.assertHasRequest(null);
  }
}
测试:
TestExpressions.java

public class MyService{
  public void assertHasRequest(@Value("#{request}") HttpServletRequest request)){
    assert request != null;
  }
}
@RunWith(SpringJUnit4ClasssRunner.class)
@ContextConfiguration(classes=Config.class)
public class TestExpressions {

  @Autowired
  MyService service;

  @Test
  public void testService(){
    service.assertHasRequest(null);
  }
}

有什么想法吗?

恐怕您不能直接在方法参数上使用
@Value
注释,这样在提供null的情况下,它就可以用默认值替换参数

在您的情况下,
@Value
注释与一起使用,并且此处理器不监视方法参数级别上的
@Value
注释

您可以将
@Value
放在方法级别,这将使Spring从上下文注入
HttpServletRequest
bean,但它不会对每个请求都这样做:

public class MyService {

    private HttpServletRequest request;

    @Value("#{request}")
    public void assertHasRequest(HttpServletRequest request) {
        if (request != null) {
            this.request = request;
        }
        assert this.request != null;
    }

}
配置类:

@Configuration
public class Config {

    @Bean
    public HttpServletRequest request() {
        HttpServletRequest mock = EasyMock.createMock(HttpServletRequest.class);
        EasyMock.expect(mock.getParameter("test")).andReturn("123").anyTimes();
        EasyMock.replay(mock);
        return mock;
    }

    @Bean
    MyService service() {
        return new MyService();
    }

}
测试等级:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=Config.class)
public class TestExpressions {

    @Autowired
    MyService service;

    @Test
    public void testService(){
        service.assertHasRequest(null);
    }
}

在Spring MVC控制器中使用
@Value
会有不同的行为。

@Value
不应该这样使用。它的主要目的是提供一种方法,在发生自动关联时为注入字段指定默认值。这一点很重要,因为当从代码中调用方法时,您似乎希望使用
@Value
,而当您调用该方法时,自动连接已经发生,并且您无法使用
@Value
更改任何已自动连接的字段<代码>@Value在实例创建时使用一次

使用
@Value
的最简单方法是:

public class MyService {

   @Value("#{request}")
   private HttpServletRequest request;

   public void assertHasRequest() {// no parameters here because they don't act on local field this.request
       assertNotNull(this.request);
   }
}
在上面的代码中,当Spring创建在
Config
类中指定的MyService实例时,它将检测
@Value
的使用,当创建
MyService
时(在调用
assertHasRequest()
之前),它将注入它找到的
请求
实例

我再举一个例子:

public class MyService {

    private HttpServletRequest request;

    public void assertHasRequest() {
        assertNotNull(this.request);
    }

    @Value("#{request}")
    private void initialize(HttpServletRequest request) {
        System.out.println("initializing request");
        this.request = request;
    }
}
在此代码中,
@Value
被放置在方法
initialize()
上。当创建
MyService
实例时,Spring容器会自动调用此方法,once。这就像一个初始化方法,目的是设置字段
请求
。如果需要,可以从代码中调用该方法,但它不会起作用
@Value
对于Spring来说意味着在创建bean实例之后知道该做什么

对于放置在方法或构造函数的参数上的
@Value
,需要使用
@Autowired

public class MyService {

    private HttpServletRequest request;

    public void assertHasRequest() {
        assertNotNull(this.request);
    }

    @Autowired
    private void initialize(@Value("#{request}") HttpServletRequest request) {
        System.out.println("initializing request: " + request);
        this.request = request;
    }
}

我不太确定你想得到什么,但它看起来很整洁。在我看来,有几个潜在的问题:1)当模拟从'request()'方法返回时,它没有处于重播模式。我想你应该叫‘EasyMock.replay(mock);’回来之前。2) assert语句正在检查提供的值是否不为null,但您可以直接使用null作为参数调用它。当然,它会抛出一个断言错误。当然你想注入请求对象并用它调用方法?@DanTemple 1)听起来合法,但没有任何改变,我将此添加到问题中。2) 是的,很酷,那么你可以按照你在测试课上的服务流程来做。因此,我们需要一个名为request的HttpServletRequest类型的变量,然后将其注释为@Autowired。然后您可以将其传递到“asserthassrequest(request)”方法,其中当前为空。@DanTemple我在另一个测试中执行此操作,我喜欢测试
@Value
而不是
@Autowire
。我不确定这是否可行,但是看一看,我认为您想用
@Component
标记
MyService
类,然后将
@ComponentScan
也放在配置类的顶部。尽管如此,我已经看到一些博客帖子声称这种类型的事情是不可能的。我的测试失败了,你自己试过了吗?是的,我试过了,今天晚些时候我会给你发送我的完整代码。嘿,junit/spring版本可以做到这一点。你能告诉我版本号吗?它应该是Spring 4。我使用3.2,看起来这就是问题所在。好的,没有使用自定义AOP注入值的情况下,
@Value
有什么替代方法吗?没有。到目前为止,我已经看到了您的代码,并询问您正在尝试做什么,但我感觉对我们两人来说,事情仍然不清楚。您的代码显示了
HttpServletRequest
,但其他任何东西都不能证明您希望在web环境中测试此功能。不过,如果您是,请看一下Spring本身。我最初的计划是在
@Service
-类上编写一个新的测试,如
void assertTestParameterIs123(@Value(${request.getParameter('Test')}”)字符串测试)
。但我现在知道,如果没有自定义AOP切入点,这是没有希望的。