2009-08-05 25 views
30

Đây là một câu hỏi kỳ lạ, nhưng nó đã làm phiền tôi trong một vài tháng nay. Tôi đã xây dựng một ứng dụng web dựa trên JPA sử dụng Wicket + Hibernate (được xây dựng với Maven) và muốn kiểm tra trực tiếp lớp DAO. Tôi đã tạo một tệp src/test/resources/META-INF/persistence.xml cụ thể mà tôi đã sử dụng để thử nghiệm, nhưng đã chạy vào xung đột với WTP và tương tự. Để giải quyết những vấn đề này, tôi đã tạo một dự án thử nghiệm riêng biệt, nơi các bài kiểm tra đơn vị trực tuyến. Có cách nào tốt hơn để quản lý các bài kiểm tra đơn vị cho một dự án JPA mà không cần phải đấu tay đôi giữa các tệp kiên trì không?Thực hành tốt nhất của JUnit dựa trên JPA Thử nghiệm

Phụ lục: Các khuôn khổ kiểm tra khác (ví dụ: TestNG) có giúp dễ dàng hơn không?

+0

Loại thử nghiệm bạn đã đề cập không phải là thử nghiệm đơn vị. Tôi nghĩ đó là thử nghiệm tích hợp kiểu. Khi bạn viết một bài kiểm tra đơn vị bạn kiểm tra một lớp học với tất cả các phụ thuộc được mô phỏng. Vì vậy, sử dụng một cơ sở dữ liệu thực (ngay cả trong bộ nhớ cơ sở dữ liệu) trong thử nghiệm đơn vị là không hợp lệ. –

+0

Nó không phải là một thử nghiệm tích hợp đầy đủ. Nó hợp lệ! Nó không phải là thử nghiệm đơn vị. – Gilberto

Trả lời

16

Bạn có thể muốn thử mockito. Thử nghiệm hoạt động như sau:

Bạn sử dụng mockito để "triển khai" EntityManager. Thay vì mã thực, bạn sử dụng các phương thức mockito để nói "nếu ứng dụng gọi getReference(), sau đó trả về đối tượng này". Trong nền, mockito sẽ tạo ra một cá thể proxy chặn các phương thức Java gọi và trả về các giá trị mà bạn chỉ định. Các cuộc gọi đến các phương thức khác sẽ trả về null.

điều Mocking như createQuery() hoạt động theo cách tương tự nhưng trước tiên bạn cần phải tạo ra một mockup của Query và sau đó sử dụng phương pháp tương tự như trong getReference() (trả lại mockup truy vấn).

Vì bạn không sử dụng EM thực, bạn không cần persistence.xml thực.

Một giải pháp đơn giản hơn nhiều sẽ là nếu bạn có thể đặt một số thuộc tính để thay đổi tên của tệp persistence.xml nhưng tôi không nghĩ rằng điều này là có thể.

Một số liên kết khác có thể giúp:

+0

Tôi đã xem xét sử dụng các đối tượng Mock (đã thực hiện nó cho các thử nghiệm dựa trên LDAP), và nó chắc chắn là một lựa chọn. Trong trường hợp cụ thể này, tôi muốn thực sự truy vấn DB để xác thực mọi thứ từ đầu đến cuối, thay vì chỉ đảm bảo rằng DAO của tôi trả về thông tin. – mlaccetti

+2

Trong trường hợp đó, có một giải pháp trong liên kết đầu tiên: Bạn có thể chỉ định một số "đơn vị bền vững" trong persistence.xml và chọn một số khác trong các bài kiểm tra đơn vị của bạn. –

4

Chúng tôi sử dụng kép persistence.xml file cho runtimes sản xuất và thử nghiệm nhưng nó là một classpath liên quan chỉ vấn đề (chúng tôi sử dụng Eclipse nhưng không dựa nhiều vào các plugin WTP). Sự khác biệt duy nhất giữa hai là phiên bản sản xuất không chứa các định nghĩa thực thể.

Chúng tôi không sử dụng khung mocking để kiểm tra JPA vì điều này sẽ không thêm bất kỳ giá trị nào vào các thử nghiệm của chúng tôi. Các thử nghiệm chạy truy cập dữ liệu thực với JPA để nói chuyện với cơ sở dữ liệu PostgreSQL.

Cách tiếp cận thử nghiệm của chúng tôi dựa trên khung kiểm tra Spring cho lớp kiên trì: thử nghiệm trong giao dịch. Ứng dụng của chúng ta dựa trên Spring nhưng cách tiếp cận này cũng có thể sử dụng được cho các ứng dụng tùy ý muốn tận dụng các lớp thử nghiệm Spring. Bản chất là mỗi thử nghiệm chạy trong một giao dịch duy nhất không bao giờ cam kết và ở cuối (trong tearDown) nó được tự động cuộn lại. Điều này giải quyết vấn đề ô nhiễm dữ liệu và kiểm tra sự phụ thuộc theo cách không phô trương và minh bạch.

Khung kiểm tra Spring là linh hoạt để cho phép thử nghiệm nhiều giao dịch nhưng đây là những trường hợp đặc biệt chiếm không quá 10% kiểm tra.

Chúng tôi vẫn sử dụng legacy support for JUnit 3.8 nhưng mới Spring TestContext Framework cho JUnit 4 trông rất hấp dẫn.

Để thiết lập dữ liệu thử nghiệm trong giao dịch, chúng tôi sử dụng lớp tiện ích nội bộ để xây dựng các thực thể nghiệp vụ. Kể từ khi nó được chia sẻ giữa tất cả các bài kiểm tra chi phí để duy trì và hỗ trợ nó là rất nhiều cân nhắc bởi những lợi ích của việc có cách tiêu chuẩn và đáng tin cậy để thiết lập dữ liệu thử nghiệm.

Spring DI giúp kiểm tra ngắn gọn và tự mô tả nhưng không phải là tính năng quan trọng.

+0

Tôi đã sử dụng JUnit 4.x (4.6, số cuối cùng, tôi tin) và phần mở rộng thử nghiệm Mùa xuân. Chúng giúp ích rất nhiều trong việc thiết lập môi trường JPA của tôi, nhưng tôi vẫn có các vấn đề kể từ khi tài liệu tham khảo persistence.xml sản xuất của tôi WEB-INF/lib/common-code.jar không hoạt động tốt với thử nghiệm. – mlaccetti

4

Sử dụng thử nghiệm đơn vị của Spring và Spring là cách tốt nhất để thực hiện. Với spring, bạn không cần hai persistence.xml vì persistence.xml của bạn không có gì trong nó, mọi thứ được chỉ rõ bởi spring (tất cả chúng ta chỉ định trong persistence.xml là tên persistence-unit) và do đó bạn có thể thay đổi cấu hình cơ sở dữ liệu vv với mùa xuân.

Và như topchef chỉ ra, thử nghiệm đơn vị dựa trên giao dịch của mùa xuân là rất tốt.

+0

Làm thế nào để bạn xác định những lớp nào cần tải và những jars nào để khai thác mã trong Spring? Tôi dường như đã bỏ lỡ một cái gì đó quan trọng. – mlaccetti

+0

Tôi sử dụng OpenJPA yêu cầu bật -javaagent trong thời gian chạy và sử dụng persistence.xml. Làm thế nào tôi nên nói với OpenJPA đại lý để tìm kiếm giữa các lớp học được đề cập trong cấu hình mùa xuân, không phải trong persistence.xml? –

+0

hmmm ... Tôi nghĩ rằng câu trả lời có thể là một chút lỗi thời. Bạn cần phải xác định trong persistence.xml của bạn một danh sách các lớp liên tục của bạn –

0

Như đã đề cập ở đây: http://www.devx.com/java/Article/36785/1954, bạn có thể loại bỏ các dòng sau từ dự án của bạn của .settings/org.eclipse.wst.common.component để tránh việc triển khai nguồn lực thử nghiệm với các ứng dụng web.

<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/> 
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/resources"/> 
Các vấn đề liên quan