2009-07-12 35 views
5

Tôi đang bắt đầu thử nghiệm đơn vị và xem lại lập trình web Java. Vấn đề là tôi không biết mình có làm đúng không.Kiểm tra đơn vị DAO, tôi có làm đúng không?

Tôi đang tạo một blog nhỏ. Tôi đang sử dụng EasyMock cho các đối tượng giả.

Dưới đây là mã của tôi:

The test case

The PostDAO

The Post Bean

Tôi thực sự muốn đánh giá cao ý kiến ​​và đề xuất của bạn về làm thế nào tôi có thể cải thiện mã của tôi và trở thành một lập trình viên tốt hơn. Cảm ơn trước!

+7

Liên kết pastebin đã chết. –

+2

mà không có các liên kết câu hỏi này mất ý nghĩa. – Asgaroth

+0

Khó theo dõi mà không cần bất kỳ mã nào ... –

Trả lời

24

Dưới đây là một số suy nghĩ để xem xét mã mini. Đưa họ cho những gì họ đang có giá trị, chỉ cần không có hành vi phạm tội:

  1. Bạn nên sử dụng JUnit 4.x thành ngữ. Không cần phải mở rộng TestCase. Sử dụng chú thích "@Test".
  2. Mocking kết nối cho DAO là vô lý. Sử dụng kết nối thực, kết nối với cơ sở dữ liệu và chạy truy vấn thực. Nếu không có điều đó, kiểm tra DAO của bạn là vô giá trị.
  3. Bạn đang bỏ lỡ một trong những cân nhắc quan trọng nhất khi kiểm tra DAO: dữ liệu. Thiết lập của bạn, như được viết, không giúp ích gì. Những gì bạn thực sự muốn là gieo một cơ sở dữ liệu với dữ liệu thử nghiệm, chạy thử nghiệm của bạn, và sau đó cuộn toàn bộ điều trở lại để nó như thể bạn chưa bao giờ ở đó. Một trong những vấn đề lớn nhất với cơ sở dữ liệu thử nghiệm là đảm bảo dữ liệu thử nghiệm của bạn có sẵn. Làm những việc như một giao dịch là cách tốt nhất để thực hiện nó.
  4. Bạn đang thử nghiệm "đường dẫn hạnh phúc", nhưng bạn không thử bất kỳ điều kiện cạnh nào cả. Mỗi người phải là một cuộc gọi thử nghiệm riêng biệt. Tôi không thể thấy lược đồ của bạn, nhưng nếu bảng của bạn cấm các giá trị null cho bất kỳ tham số nào hoặc thực thi ràng buộc duy nhất, tôi sẽ viết các kiểm tra riêng biệt để kiểm chứng thực tế đó và chứng minh rằng nó hoạt động đúng. Cách tiếp cận đúng để xử lý chúng là gì? Ném một ngoại lệ? Bạn nên suy nghĩ về nó.
  5. Xử lý lỗi của bạn kém. In tin nhắn tới bảng điều khiển không hữu ích. Bạn nên ít nhất đăng nhập nó bằng cách sử dụng log4j.
  6. Phương thức createPost của bạn có vẻ ngoài cơ sở. Bạn chuyển hai tham số và trả về một bài đăng. Thông thường với các giải pháp ORM, như Hibernate, bạn sẽ có các đối tượng tại chỗ.
  7. DAO không được tạo kết nối. Chúng phải được thông qua bởi một tầng dịch vụ biết về các đơn vị công việc và các giao dịch.
  8. Phát biểu trong đó, bạn không có logic cam kết/rollback. Cảm ơn trời, vì nó không thuộc về DAO, nhưng tôi cá là bạn chưa nghĩ về nó.
  9. Dường như bạn có nghĩa là "id" là khóa chính, nhưng tôi không thấy gì để thực sự kéo nó ra khỏi cơ sở dữ liệu sau khi INSERT của bạn và điền đối tượng. Nó sẽ không tự xảy ra.
  10. Bạn sẽ học được rất nhiều bằng cách xem hỗ trợ JDBC Spring's. Tôi muốn giới thiệu nó. Họ đã làm điều này tốt hơn bao giờ hết.
+0

10. Bạn có nghĩ rằng tôi nên thử và đi sâu vào mùa xuân? Đó thực sự là mục tiêu thực sự của tôi để tìm hiểu nó. Tôi chỉ đang làm blog mini như thực hành. Đặc biệt cảm ơn bạn duffymo vì sự kiên nhẫn và sự giúp đỡ của bạn. Cảm ơn bạn :) – user133127

+3

Vâng, tôi có thể giới thiệu Spring tận tâm. Đừng lo lắng về việc nuốt tất cả mọi thứ cùng một lúc. Bạn có thể làm điều đó theo từng mảnh. Bắt đầu với sự hỗ trợ JDBC và làm việc theo cách của bạn. – duffymo

+1

duffymo, nếu chúng ta sử dụng kết nối thực sự với DB, đây vẫn là bài kiểm tra Đơn vị? Tôi mặc dù nó trở thành tích hợp thử nghiệm, phải không? – shevchyk

2

Không liên quan đến thử nghiệm đơn vị của bạn, nhưng tôi sẽ xem xét xử lý ngoại lệ của bạn trong createPost (..) thực hành không tốt. Ngoại lệ không phải là hoàn toàn nuốt chửng, nhưng trả lại một đối tượng Post như thể tất cả mọi thứ đã ổn không phải là một ý tưởng hay. Xem Error Hiding

+0

Bạn đúng người, cảm ơn vì đã chỉ ra điều đó :) – user133127

1

Tôi nghĩ rằng nó thường ok (tôi muốn giới thiệu một chuỗi liên tục cho SQL của bạn để tránh lặp lại nó, btw).

Tất nhiên, một điều bạn không thử nghiệm với điều này là sự tương tác thực sự với cơ sở dữ liệu (vì điều này đang được mô phỏng). Vì vậy, tôi sẽ mong đợi một thử nghiệm tương ứng (hoặc thiết lập?) Mà thực sự tương tác với cơ sở dữ liệu, và chèn/rollback khi thích hợp. Nếu không, bạn đang thử nghiệm một cái gì đó (tại thời điểm này) là khá tầm thường.

Lưu ý về tổ chức kiểm tra. Các thử nghiệm dưới đây 2 điều (xây dựng không thành công thất bại, và xây dựng bình thường thành công). Tôi sẽ chia phần này thành hai bài kiểm tra, nếu không phần thứ nhất thất bại, bạn không bao giờ kiểm tra phần thứ hai (trong các tình huống phức tạp hơn, điều này làm cho chẩn đoán lỗi khó hơn, vì bạn có thể không có nhiều bằng chứng như bạn yêu cầu)

public void testPostDAO() { 
     try { 
       new PostDAO(null); 
       fail("Expected IllegalArgumentException"); 
     } catch (IllegalArgumentException ex) {} 
     new PostDAO(connectionMock); 
} 

Một số người phản đối thử nghiệm new PostDAO(null) do tầm thường của nó. Tôi không đồng ý. Một trong những lý do bạn viết kiểm tra là đảm bảo hành vi không thay đổi trừ khi bạn mong đợi nó đến. Vì vậy, ở trên là tốt - Tôi chỉ cần chia nó thành hai bài kiểm tra rõ ràng.

+0

>> Tôi muốn giới thiệu một hằng số Chuỗi Và sau đó thử nghiệm này sẽ kiểm tra những gì? Vì vậy, bạn misstype "insart" và ...? –

+0

Giới thiệu chuỗi liên tục để tránh lặp lại chuỗi và có giá trị không nhất quán/gây nhầm lẫn? Có vẻ khá rõ ràng và thực hành tốt bình thường với tôi –

+0

Nếu bạn đang đi để downvote câu trả lời, bạn có thể vui lòng cho biết lý do tại sao? Tôi không nghĩ có bất cứ điều gì đặc biệt sai/gây tranh cãi/ngoài chủ đề ở trên, phải không? –

1

Một số suy nghĩ từ beginnig của thử nghiệm của bạn:

public void testPostDAO() { 
       try { 
         new PostDAO(null); 
         fail("Expected IllegalArgumentException"); 
       } catch (IllegalArgumentException ex) {} 
       new PostDAO(connectionMock); 
     } 

Sau thay đổi này là không bắt buộc và ai đó có thể nói rằng họ là sai, nhưng đó là quan điểm của tôi:

  1. trường hợp bình thường Split và lỗi - - đó là hai hành vi khác nhau của đơn vị của bạn đang được kiểm tra

  2. Đổi tên nó thành một thứ gì đó rõ ràng hơn - để chỉ định những gì bạn đang làm - ví dụ testPostDAOWithNullArg

  3. Kiểm tra của bạn thất bại nếu không có ngoại lệ được nêu ra, làm thế nào nếu ngoại lệ WeryBadStange sẽ được nâng lên? Bạn sẽ không bắt được nó, và sẽ không bị thất bại.
+0

Nếu VeryBadStrangeException được ném, không phải nó phải được kiểm tra, hoặc nó sẽ được ném ra khỏi thử nghiệm và kích hoạt một sự thất bại? –

+0

Vâng, thực sự bạn sẽ thấy rằng một cái gì đó không thành công :) Nhưng tôi thích kiểm tra nó - một cái gì đó như - thất bại ("Mong đợi Exception1 nhưng có Exception2") - trong khuôn khổ thử nghiệm đơn vị của tôi nó mang lại cho tôi kiểm tra thất bại và hiểu rõ hơn về vấn đề hơn nếu tôi chỉ nhận được thông báo ngoại lệ lạ và kiểm tra lỗi. –

+0

Có. Kiểm tra rằng ngoại lệ rõ ràng là ném chắc chắn là một ý tưởng tốt –

2
  • Bạn đang thử nghiệm gì ở đây?IMHO điều duy nhất quan trọng ở đây là lệnh SQL của bạn vì không có logic cụ thể để kiểm tra trong DAO của bạn.
  • Kiểm tra mã init như "PostDAO mới (null)" là vô dụng khi nó đơn giản như vậy.
  • Tôi thích hsqldb ở chế độ bộ nhớ để kiểm tra dựa trên cơ sở dữ liệu thực và có ít mã giả hơn.
  • Có lý do nào khiến bạn không thể sử dụng kiểu thử nghiệm JUnit 4 bằng chú thích thay vì mở rộng TestCase như trong JUnit 3 không?
+0

1. Tôi đang thử nghiệm cả lớp. Tôi bối rối, làm cách nào để biết liệu tôi có phải thử nghiệm một thành phần của chương trình của mình hay không? 3. Ok tôi sẽ đi sâu vào hsqldb tiếp theo :) 4. Thực ra tất cả các hướng dẫn tôi đang đọc dạy JUnit 3. Có rất nhiều lý do thuyết phục để chuyển sang JUnit 4 không? – user133127

+0

BTW, bạn có thể chỉ cho tôi đúng hướng về cách kiểm tra đơn vị với hsqldb không? :) – user133127

+0

Các câu hỏi tôi tự hỏi là: Ai tự tin tôi nhận được từ các bài kiểm tra? Họ không bắt được gì? Trong PostDAOTest, nếu bạn nhập sai tên của cột cơ sở dữ liệu trong mã và cũng là kiểm tra, kiểm tra sẽ vượt qua nhưng mã sẽ có lỗi. Mocks có thể hữu ích, nhưng chúng chỉ tốt như mong đợi bạn đặt trên chúng. Một cơ sở dữ liệu đủ phức tạp đến mức sẽ rất dễ dàng để có được những kỳ vọng sai. Sử dụng một cơ sở dữ liệu trong bộ nhớ như hsqldb cho các bài kiểm tra DAO của bạn và mocks cho các lớp học nói chuyện với DAO. – NamshubWriter

1

Không có điểm nào trong Bài kiểm tra đơn vị của bạn cả. Những gì bạn đang thử nghiệm? Bạn có logic gì? Những gì nó chứng minh?

Tôi có thể thấy rằng các thử nghiệm của bạn không chứng minh được gì. Miss chèn chèn sẽ vượt qua bài kiểm tra của bạn. Đối số không hợp lệ cũng vậy.

Tôi nghĩ bạn nên sử dụng tính năng kiểm tra tích hợp hoặc chức năng tại đây. Sử dụng cơ sở dữ liệu thực. Điều này sẽ làm cho các bài kiểm tra của bạn nhẹ hơn nhiều, cộng với điều này sẽ kiểm tra mã của bạn và điều quan trọng hơn là nó sẽ chứng minh rằng mã của bạn chính xác.

+0

Xin chào, tôi làm cách nào để biết mình có phải thử nghiệm một phần chương trình của mình hay không? – user133127

+0

Nếu bạn là về bảo hiểm, mọi điều đều ổn ở đây. Chỉ cần chạy thử nghiệm chức năng và đơn vị trong một phiên. Ví dụ, chúng tôi có đặc biệt "hội nhập" cantegory rằng chúng tôi đánh dấu các bài kiểm tra truy cập vào cơ sở dữ liệu. Vì vậy, cho công việc regualar chúng tôi chỉ vô hiệu hóa các bài kiểm tra với thể loại này. Và chỉ chạy toàn bộ sute khi cần thiết. Máy chủ CI của chúng tôi cũng chạy toàn bộ. Vô lý? –

Các vấn đề liên quan