WebAppConfiguration trong Spring Test

1. Khái quát chung

Trong bài viết này, chúng ta sẽ khám phá chú thích @WebAppConfiguration trong Spring, tại sao chúng ta cần nó trong các bài kiểm tra tích hợp và cũng như cách chúng ta có thể cấu hình nó để các bài kiểm tra này thực sự khởi động một WebApplicationContext .

2. @WebAppConfiguration

Nói một cách đơn giản, đây là một chú thích cấp độ lớp được sử dụng để tạo phiên bản web của ngữ cảnh ứng dụng trong Spring Framework.

Nó được sử dụng để biểu thị rằng ApplicationContext được khởi động để thử nghiệm phải là một phiên bản của WebApplicationContext .

Lưu ý nhanh về cách sử dụng - chúng tôi thường tìm thấy chú thích này trong các bài kiểm tra tích hợp vì WebApplicationContext được sử dụng để xây dựng một đối tượng MockMvc . Bạn có thể tìm thêm thông tin về thử nghiệm tích hợp với Spring tại đây.

3. Tải một WebApplicationContext

Bắt đầu với Spring 3.2, hiện đã có hỗ trợ tải WebApplicationContext trong các thử nghiệm tích hợp:

@WebAppConfiguration @ContextConfiguration(classes = WebConfig.class) public class EmployeeControllerTest { ... } 

Điều này hướng dẫn khung TestContext rằng một WebApplicationContext nên được tải cho thử nghiệm.

Và, trong nền, một MockServletContext được tạo và cung cấp cho WebApplicationContext trong thử nghiệm của chúng tôi bằng khung TestContext .

3.1. Tùy chọn cấu hình

Theo mặc định, đường dẫn tài nguyên cơ sở cho WebApplicationContext sẽ được đặt thành “tệp: src / main / webapp”, là vị trí mặc định cho thư mục gốc của WAR trong Maven Project.

Tuy nhiên, chúng tôi có thể ghi đè điều này bằng cách chỉ cần cung cấp một đường dẫn thay thế đến chú thích @WebAppConfiguration :

@WebAppConfiguration("src/test/webapp")

Chúng tôi cũng có thể tham chiếu đường dẫn tài nguyên cơ sở từ classpath thay vì hệ thống tệp:

@WebAppConfiguration("classpath:test-web-resources")

3.2. Bộ nhớ đệm

Khi WebApplicationContext được tải, nó sẽ được lưu vào bộ nhớ đệm và sử dụng lại cho tất cả các thử nghiệm tiếp theo khai báo cùng một cấu hình ngữ cảnh duy nhất trong cùng một bộ thử nghiệm.

Để biết thêm chi tiết về bộ nhớ đệm, bạn có thể tham khảo phần Bộ nhớ đệm theo ngữ cảnh của tài liệu tham khảo.

4. Sử dụng @WebAppConfiguration trong Thử nghiệm

Bây giờ chúng ta đã hiểu tại sao chúng ta cần thêm chú thích @WebAppConfiguration trong các lớp thử nghiệm của mình, hãy xem điều gì sẽ xảy ra nếu chúng ta bỏ lỡ thêm nó khi chúng ta đang sử dụng WebApplicationContext .

@RunWith(SpringJUnit4ClassRunner.class) // @WebAppConfiguration omitted on purpose @ContextConfiguration(classes = WebConfig.class) public class EmployeeTest { @Autowired private WebApplicationContext webAppContext; private MockMvc mockMvc; @Before public void setup() { MockitoAnnotations.initMocks(this); mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build(); } ... }

Lưu ý rằng chúng tôi đã nhận xét chú thích để mô phỏng tình huống mà chúng tôi quên thêm nó vào. Ở đây, thật dễ dàng để hiểu tại sao kiểm tra sẽ không thành công khi chúng tôi chạy kiểm tra JUnit: chúng tôi đang cố gắng tự động truyền tải WebApplicationContext trong một lớp mà chúng tôi chưa đặt .

Tuy nhiên, một ví dụ điển hình hơn là thử nghiệm sử dụng cấu hình Spring hỗ trợ web; điều đó thực sự đủ để làm cho bài kiểm tra bị phá vỡ.

Chúng ta hãy có một cái nhìn:

@RunWith(SpringJUnit4ClassRunner.class) // @WebAppConfiguration omitted on purpose @ContextConfiguration(classes = WebConfig.class) public class EmployeeTestWithoutMockMvc { @Autowired private EmployeeController employeeController; ... }

Mặc dù ví dụ trên không tự động tạo WebApplicationContext, nó vẫn không thành công vì nó đang cố gắng sử dụng cấu hình hỗ trợ web - WebConfig :

@Configuration @EnableWebMvc @ComponentScan("com.baeldung.web") public class WebConfig implements WebMvcConfigurer { ... }

Chú thích @EnableWebMvc là thủ phạm ở đây - về cơ bản sẽ yêu cầu ngữ cảnh Spring được kích hoạt trên web và nếu không có nó - chúng tôi sẽ thấy kiểm tra không thành công:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.servlet.ServletContext] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at o.s.b.f.s.DefaultListableBeanFactory .raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) at o.s.b.f.s.DefaultListableBeanFactory .doResolveDependency(DefaultListableBeanFactory.java:1119) at o.s.b.f.s.DefaultListableBeanFactory .resolveDependency(DefaultListableBeanFactory.java:1014) at o.s.b.f.a.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement .inject(AutowiredAnnotationBeanPostProcessor.java:545) ... 43 more

Vì vậy, đó là vấn đề mà chúng tôi dễ dàng khắc phục bằng cách thêm chú thích @WebAppConfiguration vào các thử nghiệm của chúng tôi.

5. Kết luận

Trong bài viết này, chúng tôi đã chỉ ra cách chúng tôi có thể cho phép khung TestContext tải một WebApplicationContext vào các thử nghiệm tích hợp của chúng tôi chỉ bằng cách thêm chú thích.

Cuối cùng, chúng tôi đã xem xét các ví dụ mà mặc dù nếu chúng tôi thêm @ ContextConfiguration vào thử nghiệm, điều này sẽ không thể hoạt động trừ khi chúng tôi thêm chú thích @WebAppConfiguration .

Việc triển khai các ví dụ trong bài viết này có sẵn trong kho lưu trữ của chúng tôi trên GitHub.