Trong Kiểm thử đơn vị, tại sao tôi lại tạo Kho lưu trữ hai lần?


10

Hôm trước tôi đang đọc một chút về Kiểm thử đơn vị và tôi đã thấy một số ví dụ nơi mọi người tạo giao diện kho lưu trữ (tức là IExampleRepository) và sau đó tạo kho lưu trữ thực ( public class ExampleRepository : IExampleRepository) và kho lưu trữ được sử dụng để kiểm tra đơn vị ( FakeExampleRepository : IExampleRepository).

Trong IExampleRepositoryđó họ đã thực hiện các phương thức giống như trong ExampleRepository, tuy nhiên với các truy vấn Linq khác nhau.

Chính xác mục tiêu ở đây là gì? Tôi nghĩ rằng một phần của đơn vị kiểm tra mã của bạn có chắc chắn rằng một phương thức hoạt động chính xác không? Nhưng khi tôi sử dụng hai truy vấn hoàn toàn khác nhau, một truy vấn 'thực tế' và một truy vấn trong thử nghiệm, thử nghiệm có ý nghĩa bao nhiêu?

Câu trả lời:


8

Một trong những mục tiêu của kiểm thử đơn vị là chỉ kiểm tra một thứ tại một thời điểm, tức là một lớp và phương thức duy nhất. Nếu bản thân kho lưu trữ không được kiểm tra thì bạn thường sẽ mô phỏng điều này theo một cách nào đó để kiểm tra logic trong phương thức / lớp của bạn.

Điều đó nói rằng bạn cũng cần phải kiểm tra với kho lưu trữ 'thực' *, nhưng điều này thường sẽ được thực hiện trong kiểm tra tích hợp / hệ thống

* rõ ràng là có thật như trong repo được thiết lập để thử nghiệm, hy vọng không phải là DB sản xuất.


Vì vậy, trong thử nghiệm đơn vị, tôi sẽ không tự kiểm tra phương thức để đảm bảo rằng nó trả về các giá trị chính xác (dựa trên tập dữ liệu giả / giả)?
jao

vâng, bạn sẽ tự kiểm tra phương thức nhưng chỉ mã trong phương thức, mã trong các đối tượng khác phải được đề cập trong các thử nghiệm đơn vị khác, sự tương tác của nhiều đối tượng nên được đề cập trong các thử nghiệm tích hợp hoặc thử nghiệm cấp cao hơn
jk.

1
Ok, vì vậy nếu tôi hiểu chính xác, tôi nên sử dụng kho lưu trữ ban đầu khi đơn vị kiểm tra các kho lưu trữ. Tôi không cần phải kiểm tra chúng khi tôi đang viết các unit test cho Controllers (trong trường hợp của Asp.Net MVC)
Jao

4
@Theomax Phụ thuộc vào ngữ cảnh: nếu bạn đang kiểm tra đơn vị một thành phần phần mềm không phải của bạn ExampleRepository, thì tốt nhất nên sử dụng giả. Lý do là bạn không kiểm tra đơn vị kho lưu trữ mà là một cái gì đó khác.
Andres F.

5
@Theomax Để mở rộng nhận xét của AndresF .: Nếu bạn đang thử nghiệm đơn vị ExampleRepository, hãy sử dụng thực tế. Nếu bạn đang kiểm tra đơn vị RepositoryController, thì nó chỉ nên sử dụng một FakeExampleRepositorygiá trị trả về các giá trị được chỉ định trước. Bằng cách này, nếu một lỗi xuất hiện ExampleRepository, chỉ có bài kiểm tra đơn vị đó sẽ thất bại - RepositoryControllercác bài kiểm tra sẽ tiếp tục thành công, vì vậy bạn biết rằng không có lỗi ở đó. Nếu bộ điều khiển sử dụng kho lưu trữ thực, cả hai đều thất bại và bạn sẽ không biết mình có 1 lỗi hay 2.
Izkata

5

Tôi đồng ý với hai câu trả lời từ jk. và Jan Hudec - họ cung cấp một số thông tin thực sự tốt. Nhưng tôi nghĩ tôi sẽ thêm một chút.

Câu hỏi đầu tiên của bạn ("Chính xác mục tiêu ở đây là gì?") Rất quan trọng. Trong trường hợp bạn đang mô tả, mục tiêu thực sự là kiểm tra các lớp đang sử dụng IExampleRepositorygiao diện, không kiểm tra việc triển khai kho lưu trữ. Tạo FakeExampleRepositorycho phép bạn kiểm tra các lớp máy khách đó mà không phải lo lắng về các chi tiết của lớp kho lưu trữ thực.

Điều này đặc biệt đúng nếu đối tượng bạn đang cố thiết lập khiến việc kiểm tra trở nên khó khăn (ví dụ: truy cập hệ thống tệp, gọi dịch vụ web hoặc nói chuyện với cơ sở dữ liệu). Bằng cách sử dụng các giao diện (và các kỹ thuật khác như vậy), bạn giữ cho khớp nối ở mức thấp. Do đó, lớp Xchỉ cần biết về giao diện và không cần biết về các chi tiết thực hiện. Mục tiêu là tất cả về việc đảm bảo rằng lớp học Xđang làm đúng.

Mocking (hoặc stubbing, giả mạo ... có sự khác biệt về sắc thái) là một công cụ mạnh mẽ để thử nghiệm đơn vị và TDD. Nhưng nó có thể là một nỗi đau để tự tạo và duy trì các triển khai này. Do đó, hầu hết các ngôn ngữ hiện nay đều có thư viện chế giễu để trợ giúp. Vì bạn đang sử dụng C #, tôi khuyên dùng Moq vì nó đơn giản và rất mạnh. Sau đó, bạn có thể kiểm tra giao diện mà không cần chồng mã bổ sung cho các triển khai giả.


the real objective is to test the classes that are utilizing the IExampleRepository interfaceĐiều đó không đúng. Mục tiêu là kiểm tra nó một cách độc lập với IExampleRep repository. +1 để đề xuất một khung cách ly tốt mặc dù.
StuperUser

1
Tôi không đồng ý. Nó không độc lập với IExampleRepositoryvì lớp được kiểm tra được ghép nối với giao diện đó. Nhưng nó độc lập với bất kỳ triển khai nào của giao diện. Tôi sẽ thừa nhận rằng lời giải thích của tôi có thể sử dụng một chút khéo léo hơn mặc dù. :)
Allan

5

Chính xác mục tiêu ở đây là gì?

Sự cô lập.

Ý tưởng về một đơn vị kiểm tra nó để kiểm tra đơn vị mã nhỏ nhất có thể . Bạn làm điều này bằng cách cách ly nó khỏi tất cả các mã sản xuất khác trong thử nghiệm.

Bằng cách tạo các lớp giả, mã sản xuất duy nhất là lớp được kiểm tra.

Nếu bạn tạo một kho lưu trữ giả đúng cách và kiểm tra thất bại, bạn biết rằng vấn đề là do kiểm tra mã. Điều này cung cấp cho bạn lợi ích của chẩn đoán miễn phí.

Hãy xem các khung cách ly (như Moq như được đề xuất bởi @ ALLan) để có thể tạo ra các giả mạo này một cách nhanh chóng để thiết lập các điều kiện kiểm tra và sử dụng chúng để khẳng định.


Thêm chi tiết về hàng giả, giả và cuống: stackoverflow.com/questions/346372/ trên
StuperUser

4

Có ba lý do tại sao bạn có thể muốn cung cấp ví dụ giả cho bài kiểm tra đơn vị:

  1. Bạn muốn giới hạn phạm vi của bài kiểm tra, để bài kiểm tra không bị ảnh hưởng bởi lỗi trong depndee, có thể vì nó chưa kết thúc hoặc chưa ổn định hoặc bạn không muốn lỗi trong người khác ảnh hưởng đến bài kiểm tra của bạn.
  2. Người phụ thuộc rất phức tạp để thiết lập. Ví dụ, lớp truy cập dữ liệu thường bị chế giễu, bởi vì lớp thực đòi hỏi phải thiết lập cơ sở dữ liệu thử nghiệm. Bạn vẫn cần kiểm tra lớp truy cập dữ liệu thực, nhưng bạn có thể hạn chế cài đặt tốn kém khi gỡ lỗi những thứ khác.
  3. Để kiểm tra xem lớp phụ thuộc có phản ứng đúng với các loại lỗi khác nhau hay không, bạn cung cấp một phiên bản giả trả về tất cả các loại câu trả lời sai. Bởi vì nhiều chế độ thất bại khá khó để tái tạo, nhưng vẫn nên được kiểm tra.
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.