簡體   English   中英

集成測試期間@Context為null

[英]@Context is null during integration test

我在休息應用程序上使用spring boot 1.3.0。 我正在嘗試使用RestAssured創建集成測試。 我在@Context上遇到了問題。 它不會被注入控制器以供我獲取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));
}

這是控制器(擴展RestController的InvoiceController):

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

有沒有人遇到過這個? 如何解決這個問題?

您的控制器似乎更像是實用程序類,並且您的服務實際上是一個控制器。 因此,在這方面,您的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));
}

然后,您需要將request傳遞給InvoiceController實用程序。

但是......最優雅的解決方案就是讓JAX RS解析傳入路徑中的ID。 使用@Path您可以為路徑的命名段定義占位符,並將這些段注入到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));
  }
}

從REST Assured 2.2開始,您可以使用spring-mock-mvc模塊中的RestAssuredMockMvc ,並避免啟動Web服務器來進行測試。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = Application.class, 
    loader = AnnotationConfigWebContextLoader.class)
public class ApplicationTest {
    @Autowired
    private WebApplicationContext wac;

    @Before
    public void setUp() {
        RestAssuredMockMvc.webAppContextSetup(wac);
    }

    @Test
    public void test() {
        // your REST Assured test for any controller
    }
}

使用@Autowired注釋進行請求

@Autowired
private HttpServletRequest request;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM