java - @Context 在集成测试期间为 null

标签 java spring spring-boot integration-testing rest-assured

我在休息应用程序上使用 spring boot 1.3.0。我正在尝试使用 RestAssured 创建集成测试.我在@Context 上遇到问题。它不会被注入(inject) Controller 以供我获取 URI。

这是测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebIntegrationTest("server.port=8080")
@ActiveProfiles(value = {"testing"})
public class InvoiceRestServiceIT {

    private static String INVOICE_DATA = "<invoice data>";
    private static String INVOICE_URL = "/customers/1q2w3e4r/invoices";

    @Test
    public void testPostInvoice() {
        given()
           .contentType(ContentType.JSON)
           .accept(ContentType.JSON)
           .body(INVOICE_DATA)
         .expect()
            .statusCode(200)
            .body(containsString("entity"), containsString("id"))
         .when()
            .post(INVOICE_URL);;
    }
}

这是服务类(InvoiceRestService.java):

@Autowired
private InvoiceController invoiceController;

@POST
public EntityResponse add(InvoiceResource invoiceResource) {
    return new EntityResponse(invoiceController.createInvoice(invoiceResource));
}

这是 Controller (InvoiceController 扩展 RestController):

protected Customer getCustomer() {
    Customer customer = customerRepository.findOne(getCustomerId());
...
}

这里是错误发生的地方(RestController.java):

@Context
private HttpServletRequest request;

protected String getCustomerStringId() {
    Matcher matcher = pattern.matcher(request.getRequestURI()); //<---- Here, request object is null
    if (!matcher.find()) {
        throw new IllegalStateException("Cannot find customer id in request URL");
    }

    return matcher.group(1);
}

这是错误日志:

java.lang.NullPointerException: null
at org.store.rest.RestController.getCustomer(RestController.java:90)
at org.store.rest.invoice.InvoiceController.createInvoice(InvoiceController.java:87)
at org.store.rest.invoice.InvoiceController$$FastClassBySpringCGLIB$$2d6c1a2e.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at com.store.rest.invoice.InvoiceController$$EnhancerBySpringCGLIB$$90cabdc3.createInvoice(<generated>)
at com.store.rest.invoice.InvoiceRestService.add(InvoiceRestService.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497

有人遇到过吗?如何解决这个问题?

最佳答案

看来您的 Controller 更像是实用程序类,而您的服务实际上是一个 Controller 。因此,在这方面,您的 InvoiceController 可能不是 JAX RS 根资源。

我认为最简单的解决方案(如果你想继续沿这条路线)是删除 @Context private HttpServletRequest request;RestController 中的声明并将其移动到 InvoiceRestService 像这样:

@POST
public EntityResponse add(InvoiceResource invoiceResource, @Context HttpServletRequest request) {
    return new EntityResponse(invoiceController.createInvoice(invoiceResource, request));
}

然后您需要将请求传递给您的InvoiceController 实用程序。

但是...最优雅的解决方案是让 JAX RS 从传入路径中解析 ID。使用 @Path,您可以为路径的命名段定义占位符,并将这些段注入(inject)到您的 JAX RS 端点方法中,如下所示:

@Path("/customers/{customerId}/invoices")
public class InvoiceRestService {

  @POST
  public EntityResponse add(@PathParam("customerId") String customerId, InvoiceResource invoiceResource) {
    return new EntityResponse(invoiceController.createInvoice(invoiceResource, customerId));
  }
}

关于java - @Context 在集成测试期间为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36437121/

相关文章:

java - Maven:Hibernate 版本错误?

java - 当我尝试清除所有数据时,应用程序已停止

android - 如何使用 Spring Boot Server 无限期地保持 Android 应用程序登录?

java - 如何将Java泛型应用于计算器?

java - JFrame 采用奇怪的背景

html - 如何使用 Spring 和 Thymeleaf 在属性文件中存储 URL 并在模板中访问它们

java - 使用 Spring MVC 提供静态内容并渲染 JSP

java - 当我尝试在 postman 中返回消息时出现额外的空值

java - 为什么我无法使用 Spring Boot 在 Spring 上下文中获取可用的 Bean 定义?

java - Spring Boot jpa 与 H2 数据库