Có hữu ích cho các phương pháp kiểm tra đơn vị trong đó logic duy nhất là bảo vệ không?


12

Nói rằng tôi có một phương pháp như thế này:

public void OrderNewWidget(Widget widget)
{
   if ((widget.PartNumber > 0) && (widget.PartAvailable))
   {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

Tôi có một số phương thức như vậy trong mã của mình (nửa trước cho một cuộc gọi Dịch vụ web không đồng bộ).

Tôi đang tranh luận nếu nó hữu ích để làm cho chúng được bảo hiểm với các bài kiểm tra đơn vị. Vâng, có logic ở đây, nhưng nó chỉ là logic bảo vệ. (Có nghĩa là tôi đảm bảo rằng tôi có những thứ tôi cần trước khi cho phép cuộc gọi dịch vụ web xảy ra.)

Một phần trong tôi nói rằng "chắc chắn bạn có thể đơn vị kiểm tra chúng, nhưng nó không đáng thời gian" (Tôi đang trong một dự án đã bị chậm tiến độ).

Nhưng mặt khác của tôi nói, nếu bạn không thử nghiệm chúng và ai đó thay đổi Vệ binh, thì có thể có vấn đề.

Nhưng phần đầu tiên của tôi nói lại, nếu ai đó thay đổi lính canh, thì bạn chỉ đang làm thêm cho họ (vì bây giờ họ phải thay đổi lính canh và đơn vị kiểm tra cho lính canh).

Ví dụ: nếu dịch vụ của tôi nhận trách nhiệm kiểm tra tính khả dụng của Widget thì tôi có thể không muốn người bảo vệ đó nữa. Nếu nó đang được thử nghiệm đơn vị, tôi phải thay đổi hai nơi ngay bây giờ.

Tôi thấy ưu và nhược điểm theo cả hai cách. Vì vậy, tôi nghĩ rằng tôi sẽ hỏi những gì người khác đã làm.


17
Bạn không tạo ra "nhiều việc hơn" cho những người bảo trì. Nếu họ thay đổi logic, họ phải thay đổi các bài kiểm tra đơn vị tương ứng. Đó là cách nó hoạt động. Tôi không thấy khuyết điểm của bạn: nếu bài kiểm tra đơn vị của bạn không yêu cầu thay đổi, thì nó sẽ không kiểm tra bất cứ điều gì, phải không? Bạn cũng có thể đặt câu hỏi liệu thử nghiệm đơn vị có hữu ích không.
Andres F.

9
Đây không phải chủ đề, nhưng tôi sẽ thay đổi logic để đưa ra một ngoại lệ nếu số phần bằng 0 hoặc ít hơn hoặc nếu phần đó không có sẵn, vì theo tôi, đó sẽ là một lỗi để cho phép ai đó gọi phương thức đó bằng một phụ tùng không có thật, âm thầm che giấu một vấn đề khác.
Matthew

2
@Matthew điểm rất tốt. Chức năng này nằm. Việc đặt tên cho bạn biết nó sẽ đặt thứ gì đó. Và sau đó thì không nhưng bạn sẽ không bao giờ biết, trừ khi bạn áp dụng logic tương tự như bên trong, điều này làm mất đi DRY. Nói cách khác: nếu thiết kế được thay đổi để chính xác hơn, câu hỏi này có thể sẽ không được hỏi ngay từ đầu.
stijn

2
but it is not worth the time" (I am on a project that is already behind schedule).Chúng tôi là nhà phát triển phần mềm. Lần duy nhất chúng tôi có trong lịch trình là khi chúng tôi chết :)
maple_shaft

Câu trả lời:


26

Một phần trong tôi nói rằng "chắc chắn bạn có thể đơn vị kiểm tra chúng, nhưng nó không đáng thời gian" (Tôi đang trong một dự án đã bị chậm tiến độ).

Đó là ba bài kiểm tra rất ngắn. Bạn đã dành nhiều thời gian để tự hỏi mình câu hỏi.

Nhưng mặt khác của tôi nói, nếu bạn không thử nghiệm chúng và ai đó thay đổi Vệ binh, thì có thể có vấn đề.

Nghe bên này.

Nhưng phần đầu tiên của tôi nói lại, nếu ai đó thay đổi lính canh, thì bạn chỉ đang làm thêm cho họ (vì bây giờ họ phải thay đổi lính canh và đơn vị kiểm tra cho lính canh).

Nếu người bảo trì của bạn là một hạt TDD, bạn sẽ gây khó khăn hơn cho họ. Bất kỳ thay đổi nào tôi thực hiện mà không có thay đổi liên quan hoặc bổ sung các bài kiểm tra dẫn đến tôi phải suy nghĩ kỹ. Trên thực tế, tôi có thể sẽ thêm các bài kiểm tra trước khi tôi tiếp tục và thực hiện thay đổi.

Phần đầu tiên của bạn chỉ đơn giản là sai. Cho phần thứ hai vỗ nhẹ vào lưng và ngừng suy nghĩ về nó.


+1 cho sự cô đọng mặc dù tôi cũng đã viết một câu trả lời heh
Jimmy Hoffa

3
+1. Có, nếu các yêu cầu thay đổi, một số thử nghiệm sẽ phải được điều chỉnh.
Olivier Jacot-Descombes

Trong khi tôi thích những gì bạn nói, tôi có nhiều trường hợp của loại cuộc gọi này trong mã của tôi (nửa trước của một cuộc gọi không đồng bộ). Vì vậy, nó không chỉ là 3 bài kiểm tra đơn vị. Tuy nhiên, nếu đó là cách "đúng" thì tôi muốn hoàn thành chúng.
Núi lửa

@Vaccano: Bạn càng phải viết nhiều bài, bạn càng có nhiều đường dẫn logic hơn và không cần thiết phải viết chúng.
pdr

9

Nó sẽ đơn giản hóa việc kiểm tra đơn vị nếu logic bảo vệ và thứ tự thực tế là các phương thức riêng biệt.

Trong Widgetlớp

public bool IsReadyForOrdering { get { return PartNumber > 0 && PartAvailable; } }

hoặc một phương thức tương đương ở một nơi khác

public bool IsWidgetReadyForOrdering(Widget widget)
{
    return widget.PartNumber > 0 && widget.PartAvailable;
}

Phương thức đặt hàng

public void OrderNewWidget(Widget widget)
{
   if (IsWidgetReadyForOrdering(widget)) {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

Bây giờ thử nghiệm IsWidgetReadyForOrderingđã trở nên dễ dàng. Đừng suy nghĩ một thời gian dài về nó nữa. Kiểm tra nó!


1
Oof, logic trạng thái trong một thuộc tính .. -1 đó phải là một phương thức và nó sẽ lấy PartNumber, PartAv Available do tính đơn giản của nó. Làm cho nó được bảo vệ nếu nó không cần phải là một phần của API công khai nhưng không phải là một tài sản .. Ngoài ra tôi thường không đồng ý. Logic bảo vệ bên trong phương thức này hoàn toàn tốt, và trong mắt tôi tốt hơn bởi vì đó là một phương thức nhỏ như vậy bạn chỉ đang làm ô nhiễm lớp để làm cho một phương thức vốn đã nhỏ hơn. Thêm nó vào lớp trong trường hợp này chỉ khi nó lặp đi lặp lại logic.
Jimmy Hoffa

1
Đầu tiên, điều này không trả lời câu hỏi. Thứ hai, nó không đúng sự thật. Bạn cần phải viết ba bài kiểm tra một trong hai cách. Thứ ba, nó phơi bày chi tiết thực hiện để gọi mã, không cần thiết.
pdr

8
@JimmyHoffa: bạn thấy bất kỳ logic trạng thái nào trong tài sản đó? Trong thực tế, ví dụ cho thấy cách tách logic thay đổi trạng thái (OrderNewWidget) khỏi logic không statechanging (ReadyForOrdering). Và tôi là một người tin tưởng mạnh mẽ rằng việc trích xuất ngay cả các hàm nhỏ đó sẽ cải thiện mã, và không làm cho nó tồi tệ hơn, như bạn nêu. Vậy +1.
Doc Brown

2
Phương thức OrderNewWidgetnày có thể ở một lớp khác hơn Widget, vì nó có một Widgetđối số. Vì phương thức này không có giá trị trả về, nên việc kiểm tra nó không rõ ràng. Bạn sẽ phải tiêm một WigdetOrderingService-mock theo dõi OrderNewWidgetAsynccuộc gọi.
Olivier Jacot-Descombes

2
@JimmyHoffa: thực ra, định nghĩa của bạn về "không quốc tịch" có nghĩa là "tĩnh" trong C #. Vì vậy, những gì bạn nói là "thuộc tính không nên truy cập trạng thái của một đối tượng". Nhưng ngay cả các getters câm truy cập các biến trạng thái, vì vậy điều đó có nghĩa là "chỉ ghi các thuộc tính tĩnh" - dường như không có nhiều ý nghĩa.
Doc Brown

6

Nếu bạn không có thời gian trong lịch trình để kiểm tra đơn vị nhưng bạn có thời gian dành cho việc sử dụng QA vững chắc, thì hãy hỏi xem bạn có thể ăn cắp một số thời gian QA đó để viết bài kiểm tra đơn vị không, hoặc bạn có thể dành thời gian cho QA không thực hiện các bài kiểm tra đơn vị, hoặc có lẽ chỉ là đối phó với mã không được kiểm tra đơn vị .. Thật không may, lịch trình không thể thay đổi buộc bạn phải nhượng bộ hoặc tự mình làm việc đến chết, tôi thường đề xuất lựa chọn đầu tiên bởi vì cách thứ hai sẽ khiến bạn không thể hỗ trợ / duy trì hệ thống chính xác cho thời hạn của nó.

Điều đó nói rằng, đối với câu hỏi chung của bạn về kiểm tra tuyên bố bảo vệ; Đúng! Hoàn toàn kiểm tra tuyên bố bảo vệ! Đó là những bộ phận quan trọng của hành vi của phương pháp này, bạn sẽ không muốn tìm hiểu ai đó hiểu lầm gì đó làm một lỗi-sửa chữa và loại bỏ bảo vệ hoặc thay đổi &&một ||phải không? Các bài kiểm tra đơn vị sẽ đảm bảo rằng a) bạn thực sự hiểu logic của các vệ sĩ của mình và b) không ai phá vỡ logic đó sau đó mà không nhận được khiếu nại khi họ chạy các bài kiểm tra đơn vị nói với họ rằng đó là lý do.


0

Có một số câu trả lời xuất sắc ở trên, và những điểm họ đưa ra rất quan trọng. Nhưng một điều dường như đã bị bỏ lỡ là trong số các bạn có một bộ kiểm tra đơn vị toàn diện, chúng đọc giống như một đặc tả cực kỳ chi tiết của mã. Nếu bạn bỏ qua kiểm tra xác thực chỉ vì mã quá dễ, thật khó để xem làm thế nào nó có thể sai, một phần đặc tả của bạn bị thiếu. Nếu tôi tham gia vào một nhóm mà các bài kiểm tra này đã bị bỏ lỡ, tôi thực sự sẽ cho rằng dịch vụ của bạn không xác thực các đối số của nó.


-5

Mã là mã. Bạn nên cố gắng để có được bảo hiểm 100% khi thử nghiệm. Nếu nó không quan trọng thì nó sẽ không ở đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.