2009-09-02 52 views
21

Tôi có một bài kiểm tra đơn vị được gọi là TestMakeAValidCall(). Nó kiểm tra ứng dụng điện thoại của tôi thực hiện cuộc gọi hợp lệ.Kiểm tra đơn vị - Có phải là hình thức không tốt để thử nghiệm đơn vị gọi các bài kiểm tra đơn vị khác

Tôi sắp viết một bài kiểm tra khác gọi là TestShowCallMessage() cần phải có cuộc gọi hợp lệ được thực hiện cho bài kiểm tra. Có phải là hình thức xấu để chỉ gọi TestMakeAValidCall() trong thử nghiệm đó?

Để tham khảo, đây là thử nghiệm TestMakeAValidCall() của tôi.

[TestMethod] 
    public void TestMakeAValidCall() 
    { 
     //Arrange 
     phone.InCall = false; 
     phone.CurrentNumber = ""; 
     // Stub the call to the database 
     data.Expect(x => x.GetWhiteListData()). 
      Return(FillTestObjects.GetSingleEntryWhiteList()); 
     // Get some bogus data 
     string phoneNumber = FillTestObjects.GetSingleEntryWhiteList(). 
      First().PhoneNumber; 
     // Stub th call to MakeCall() so that it looks as if a call was made. 
     phone.Expect(x => x.MakeCall(phoneNumber)). 
      WhenCalled(invocation => 
         { 
          phone.CurrentNumber = phoneNumber; 
          phone.InCall = true; 
         }); 

     //Act 
     // Select the phone number 
     deviceControlForm.SelectedNumber = phoneNumber; 
     // Press the call button to make a call. 
     deviceMediator.CallButtonPressed(); 

     //Assert 
     Assert.IsTrue(phone.InCall); 
     Assert.IsTrue(phone.CurrentNumber == phoneNumber); 
    } 
+0

Cảm ơn tất cả các câu trả lời tuyệt vời. Tôi đã tái cấu trúc mã trùng lặp thành một cuộc gọi riêng biệt. Tôi đã chọn câu trả lời với nhiều phiếu nhất. – Vaccano

Trả lời

51

Tái cấu trúc thiết lập sang phương pháp khác và gọi phương thức đó từ cả hai thử nghiệm. Các xét nghiệm không nên gọi các xét nghiệm khác.

+3

Không kiểm tra một thử nghiệm khác với thử nghiệm –

+0

Ai đó có thể lập phương sai về cách tái cấu trúc sẽ trông như thế nào trong trường hợp này? –

+1

@Nakata - khó hiển thị mã chính xác cho ví dụ này mà không biết cách phụ thuộc được cấu trúc, nhưng gist này cho thấy mẫu tôi sử dụng để đặt mã trong ngữ cảnh thử nghiệm và gọi nó từ đó trong nhiều thử nghiệm. https://gist.github.com/tvanfosson/1ca6dd3bb0b796de65b0 – tvanfosson

6

Tôi nghĩ đó là một ý tưởng tồi. Bạn muốn thử nghiệm đơn vị của bạn để kiểm tra một điều và một điều duy nhất. Thay vì tạo cuộc gọi thông qua thử nghiệm khác của bạn, hãy thực hiện cuộc gọi và chuyển cuộc gọi đó làm đối số.

11

IMHO, bạn nên làm một trong các cách sau:

  • Tạo một phương thức trả về một cuộc gọi hợp lệ, và sử dụng nó một cách riêng biệt cho cả các bài kiểm tra (không phải là một cách gọi khác)
  • Mock cuộc gọi hợp lệ cho ShowCallMessageTest
4

Kiểm tra đơn vị phải kiểm tra một đơn vị/chức năng của mã theo định nghĩa. Có nó gọi kiểm tra đơn vị khác làm cho nó kiểm tra nhiều hơn một đơn vị. Tôi chia nó thành các bài kiểm tra riêng lẻ.

2

Có - kiểm tra đơn vị phải tách biệt và chỉ nên thử nghiệm một điều (hoặc ít nhất một số lượng nhỏ các thứ liên quan chặt chẽ). Là một sang một bên, các cuộc gọi đến data.Expect và phone.Expect trong phương pháp thử nghiệm của bạn đang tạo ra kỳ vọng chứ không phải là ... Điện thoại

+0

Cảm ơn bạn đã sửa đổi về thuật ngữ của tôi. Tôi đã cập nhật các nhận xét trong Mã nguồn của mình. – Vaccano

6

Để cung cấp một điểm truy cập:

Tôi tin tưởng rằng kiểm tra đơn vị được thiết kế tốt nên phụ thuộc vào nhau!

Tất nhiên, điều đó chỉ có ý nghĩa nếu khung kiểm tra nhận thức được những phụ thuộc này để có thể ngừng chạy kiểm tra phụ thuộc khi phụ thuộc không thành công. Thậm chí tốt hơn, một khuôn khổ như vậy có thể vượt qua vật cố từ thử nghiệm để kiểm tra, như vậy có thể xây dựng dựa trên một vật cố định đang phát triển và mở rộng thay vì xây dựng lại nó từ đầu cho từng thử nghiệm đơn lẻ. Tất nhiên, bộ nhớ đệm được thực hiện để chăm sóc không có tác dụng phụ được giới thiệu khi nhiều hơn một thử nghiệm phụ thuộc từ ví dụ tương tự.

Chúng tôi đã triển khai ý tưởng này trong JExample extension for JUnit. Chưa có cổng C#, mặc dù có các cổng cho RubySmalltalk và ... most recent release of PHPUnit picked up both our ideas: dependencies and fixture reuse.

PS: folks are also using it for Groovy.

+0

Điểm thú vị, nếu được thực hiện một cách chính xác, nó có thể giảm trùng lặp rất nhiều. –

1

Một đơn vị so với mô-đun .... chúng tôi cũng nghĩ rằng các thử nghiệm cũng nên phụ thuộc vào các phương pháp có thể tái sử dụng và nên kiểm tra ở mức tích hợp thử nghiệm mức api của các lớp. Nhiều người chỉ cần kiểm tra một lớp duy nhất nhưng nhiều lỗi ở mức tích hợp đó giữa cấp lớp. Chúng tôi cũng sử dụng verifydesign để đảm bảo api không phụ thuộc vào việc triển khai. Điều này cho phép bạn cấu trúc lại toàn bộ thành phần/mô-đun mà không cần chạm vào một thử nghiệm (và chúng tôi đã thực hiện điều đó một lần và nó hoạt động tốt).Tất nhiên, bất kỳ thay đổi kiến ​​trúc nào buộc bạn phải tái cấu trúc các thử nghiệm nhưng ít nhất là thay đổi thiết kế trong mô-đun không gây ra công việc tái cấu trúc thử nghiệm (trừ khi bạn thay đổi hành vi của api tất nhiên ngầm như bắn nhiều sự kiện hơn bạn đã từng sử dụng nhưng " sẽ "là một thay đổi api anyways).