2008-11-24 24 views
10

Tôi hiểu cần phải kiểm tra một lớp học có logic (ví dụ: một lớp có thể tính toán giảm giá), nơi bạn có thể kiểm tra lớp thực tế.Tại sao tôi viết một lớp giả và đơn vị kiểm tra nó?

Nhưng tôi mới bắt đầu viết các bài kiểm tra đơn vị cho một dự án sẽ hoạt động như một kho lưu trữ (lấy các đối tượng từ cơ sở dữ liệu). Tôi thấy mình đang viết một kho chứa 'giả' thực hiện giao diện ISomethingRepository. Nó sử dụng một Dictionary<Guid, Something> để lưu trữ nội bộ. Nó thực hiện các phương thức Add(Something)GetById(Guid) của giao diện.

Tại sao tôi viết nội dung này? Không có gì tôi viết sẽ thực sự được sử dụng bởi phần mềm khi nó được triển khai, đúng không? Tôi không thực sự thấy giá trị của bài tập này.

Tôi cũng có lời khuyên để sử dụng đối tượng giả mà tôi có thể thiết lập trước để đáp ứng các kỳ vọng nhất định. Điều đó dường như thậm chí còn vô nghĩa đối với tôi: tất nhiên thử nghiệm sẽ thành công, tôi đã chế nhạo/giả mạo nó để thành công! Và tôi vẫn không chắc chắn phần mềm thực tế sẽ thực hiện như mong muốn khi kết nối với cơ sở dữ liệu ...

nhầm lẫn ...

Ai đó có thể chỉ cho tôi đi đúng hướng để giúp tôi hiểu điều này ?

Cảm ơn bạn!

+0

Tôi upvoting điều này, bởi vì đây là một cái gì đó mà irks tôi thường xuyên. Những người ủng hộ TDD nhanh nhất có xu hướng rơi vào tình huống vô tình này và kết thúc các kịch bản/mã thử nghiệm không xảy ra trong thực tế. – FlySwat

Trả lời

13

Bạn không thử nghiệm đối tượng giả của mình nhưng một số lớp khác tương tác với nó. Vì vậy, bạn có thể cho ví dụ kiểm tra rằng một bộ điều khiển chuyển tiếp một cuộc gọi phương thức lưu vào kho lưu trữ giả của bạn. Có điều gì đó sai nếu bạn "thử nghiệm các đối tượng giả mạo của mình"

+1

Vâng, đó là những gì tôi nghĩ. Vì vậy, sau đó tôi có ý tưởng sai về việc kiểm tra mã truy cập dữ liệu của mình. Ví dụ: http://tinyurl.com/6qojvh –

+0

Xin lỗi, đây có phải là câu hỏi không? – mmiika

+0

Vâng, tôi đã tự hỏi ý kiến ​​của bạn là gì về bài viết đó trong bối cảnh thảo luận của chúng tôi. –

0

Bạn viết lớp "giả" được gọi là đối tượng Stub hoặc Mock vì bạn muốn thử nghiệm triển khai một cách đơn giản mà không cần kiểm tra lớp bê tông thực. Mục đích là để đơn giản hóa việc kiểm tra bằng cách chỉ kiểm tra Giao diện (hoặc lớp trừu tượng).

Trong ví dụ của bạn, bạn đang thử nghiệm một thứ có từ điển. Nó có thể được lấp đầy trong thực tế bởi cơ sở dữ liệu hoặc có rất nhiều logic đằng sau nó. Trong đối tượng "giả" của bạn, bạn có thể đơn giản hóa mọi thứ bằng cách có tất cả dữ liệu không đổi. Bằng cách này bạn chỉ kiểm tra hành vi của giao diện chứ không phải cách đối tượng cụ thể được xây dựng.

+0

Tôi hiểu, nhưng điều đó có giá trị như thế nào? Tôi đã viết * giả * và thử nghiệm nó. Nó không được sử dụng trong mã sản xuất ở bất cứ đâu. Vậy tại sao viết nó và kiểm tra nó? –

+1

Để kiểm tra việc triển khai của bạn mà không cần phải có phần tử bê tông đường dẫn của bạn. Bạn có thể đưa ra rất nhiều mã và tập trung vào mục đích thử nghiệm của bạn. Ví dụ của tôi trong bài viết của tôi là tốt ... databse một ... bạn không cần phải có một "cơ sở dữ liệu thực" và bạn có thể giả mạo nó ... –

2

Mục đích của đối tượng giả/bài không phải là để được kiểm tra thay của đơn vị bạn đang cố gắng để kiểm tra, nó cho phép bạn kiểm tra đơn vị đó mà không cần lớp khác.

Về cơ bản, bạn có thể kiểm tra từng lớp một mà không phải kiểm tra tất cả các lớp mà chúng cũng phụ thuộc vào.

+0

Vâng, đó là những gì tôi nghĩ. Vì vậy, trong một lớp 'cao hơn' mà thường sử dụng mã kho, tôi có thể tiêm một mô hình để thử nghiệm để nó sẽ không thực sự kết nối với cơ sở dữ liệu, đúng không? –

+2

Ngay trên đó –

1

Ai xem người xem?

Thật là thú vị ví dụ nếu việc thực hiện mô hình ném ngoại lệ cụ thể đối với các trường hợp góc, vì vậy bạn biết rằng các lớp học sử dụng hoặc phụ thuộc các IRepositorySomething thể xử lý các trường hợp ngoại lệ được ném vào cuộc sống thực. Một số ngoại lệ mà bạn không thể tạo dễ dàng với cơ sở dữ liệu thử nghiệm.

Bạn không kiểm tra đối tượng Mock bằng thử nghiệm đơn vị, nhưng bạn sử dụng nó để kiểm tra các lớp phụ thuộc vào nó.

+0

Tôi đã tìm thấy những trường hợp đặc biệt để trở thành một trong những điều hữu ích nhất bạn có thể làm với một mô hình. +1 –

3

Đừng kiểm tra lớp giả. Làm kiểm tra lớp sản xuất bằng cách sử dụng lớp giả.

Toàn bộ điểm của lớp hỗ trợ kiểm tra là có thứ gì đó mà bạn có thể dự đoán hành vi của nó. Nếu bạn cần kiểm tra lớp hỗ trợ kiểm tra để dự đoán hành vi của nó, có sự cố.

Trong bài viết cơ sở dữ liệu giả bạn đã liên kết trong nhận xét, tác giả cần đơn vị kiểm tra cơ sở dữ liệu giả mạo của mình vì đó là sản phẩm của anh ấy (ít nhất là trong ngữ cảnh của bài viết).

Chỉnh sửa: các điều khoản được cập nhật phải nhất quán hơn.

  • Mock - được tạo ra bởi chế giễu khuôn khổ
  • Fake - tạo ra bằng tay, thực sự có thể hoạt động một số.
  • Hỗ trợ kiểm tra - Mocks, Fakes, Stubs và tất cả phần còn lại. Không sản xuất.
+0

"Hãy thử nghiệm lớp sản xuất bằng cách sử dụng lớp giả" Ok, vì vậy nếu lớp truy cập dữ liệu sản xuất của tôi sử dụng NHibernate, tôi nên thử NHibernate, và sau đó kiểm tra lớp sản xuất? Vì vậy, một phần NHibernate của lớp sản xuất nên được tiêm. Và không cần phải viết lớp truy cập dữ liệu giả mạo? –

+1

Phải. bạn nên chế nhạo NHib, và không cần phải cung cấp giả mạo. Trừ khi hợp đồng công khai của NHIB quá rộng ... thì bạn nên bọc NHib và giả mạo trình bao bọc. –

+0

Nhưng kể từ khi dataacess của bạn đã kết thúc NHIB từ phần còn lại của ứng dụng ... giả lập dataacess của bạn để kiểm tra phần còn lại của ứng dụng (giá trị nhất). –

1

Bạn không nên thử nghiệm lớp giả.

Điều bạn thường làm là: bạn tạo các lớp mô phỏng cho tất cả các lớp mà lớp bạn đang thử nghiệm tương tác với.

Giả sử bạn đang thử nghiệm một lớp được gọi là Xe đạp có các đối tượng hàm tạo của các lớp Wheel, Saddle, HandleBar, v.v.

Và sau đó trong lớp Xe đạp bạn muốn thử nghiệm phương pháp của nó GetWeight có thể lặp qua từng phần và gọi thuộc tính/phương pháp Trọng lượng của chúng và sau đó trả về tổng.

Những gì bạn cần làm:

  • bạn viết một lớp học giả cho từng phần (Wheel, yên vv) mà chỉ đơn giản thực hiện các Trọng lượng cắn
  • sau đó bạn vượt qua những lớp học giả cho xe đạp
  • kiểm tra phương thức GetWeight GetWeight trên lớp Xe đạp

Bằng cách đó bạn có thể ocus khi thử nghiệm GetWeight trên lớp Xe đạp, theo cách độc lập với các lớp khác (nói rằng chúng chưa được triển khai, không xác định, v.v.)

1

Thay vì tự viết một lớp giả, bạn có thể sử dụng một công cụ (như Rhino hoặc Typemock) để giả lập nó. Nó dễ dàng hơn nhiều so với viết tất cả các mocks mình. Và giống như những người khác nói, không cần phải kiểm tra mã giả, đó là không có mã nếu bạn sử dụng công cụ.

1

Tôi thực sự đã tìm thấy hai cách sử dụng cho các lớp mô hình mà chúng tôi sử dụng trong thử nghiệm triển khai kho lưu trữ.

Đầu tiên là kiểm tra các dịch vụ sử dụng triển khai tương đương "ISomethingRepository" mà bạn đề cập. Tuy nhiên, việc triển khai kho lưu trữ của chúng tôi được tạo bởi một nhà máy. Điều này có nghĩa là chúng tôi viết các bài kiểm tra đối với "ISomethingRepository", nhưng không chống lại "MockSomethingRepository" trực tiếp. Bằng cách thử nghiệm dựa trên giao diện, chúng tôi có thể dễ dàng khẳng định rằng phạm vi mã cho các thử nghiệm của chúng tôi bao gồm 100% giao diện.Đánh giá mã cung cấp xác minh đơn giản rằng các thành viên giao diện mới được kiểm tra. Ngay cả khi các nhà phát triển đang chạy với giả thiết mà nhà máy trả về, máy chủ xây dựng có cấu hình khác nhau để kiểm tra việc thực thi cụ thể mà nhà máy trả về trong các bản dựng hàng đêm. Nó cung cấp tốt nhất của cả hai thế giới, về phạm vi kiểm tra và hiệu suất địa phương.

Việc sử dụng thứ hai là một trong những điều mà tôi ngạc nhiên khi không ai khác đề cập đến. Nhóm của tôi chịu trách nhiệm cho tầng lớp trung lưu. Các nhà phát triển web của chúng tôi chịu trách nhiệm về giao diện người dùng của các sản phẩm web. Bằng cách xây dựng việc triển khai kho lưu trữ giả, không có trở ngại nhân tạo nào để chờ cơ sở dữ liệu được mô hình hoá và triển khai trước khi bắt đầu công việc đầu cuối. Các khung nhìn có thể được viết sẽ được xây dựng dựa trên mô hình để cung cấp một lượng dữ liệu "thực" tối thiểu để đáp ứng sự mong đợi của các nhà phát triển web. Ví dụ: dữ liệu có thể được cung cấp để chứa dữ liệu chuỗi độ dài tối thiểu và tối đa để xác minh rằng không phá vỡ triển khai của chúng, v.v.

Vì các nhà máy chúng tôi sử dụng có dây để "ISomethingRepository" trở lại, chúng tôi có cấu hình thử nghiệm cục bộ , xây dựng các cấu hình thử nghiệm, cấu hình sản xuất, v.v. Chúng tôi cố tình cố gắng đảm bảo rằng không có nhóm nào trong dự án có thời gian chờ đợi không hợp lý vì thời gian thực hiện của một nhóm khác. Thời gian chờ đợi lớn nhất vẫn được cung cấp bởi nhóm phát triển, nhưng chúng tôi có thể đẩy mạnh các đối tượng miền, kho lưu trữ và dịch vụ của mình với tốc độ nhanh hơn so với phát triển front-end.

Tất nhiên, YMMV. ;-)

0

Hãy nhìn vào bài viết sau đây cho một lời giải thích tốt về điều này:

http://msdn.microsoft.com/en-us/magazine/cc163358.aspx

Về cơ bản, nếu bạn viết một đối tượng giả mạo và nó hóa ra là khá phức tạp, nó là đôi khi giá trị nó để kiểm tra đơn vị giả để đảm bảo nó hoạt động như mong đợi.

Vì kho lưu trữ có thể phức tạp nên việc kiểm tra đơn vị cho nó thường có ý nghĩa.

0

Thường không cần chạy thử nghiệm đơn vị cổ điển trong Lớp Truy cập dữ liệu. Có lẽ bạn có thể viết kiểm tra đơn vị kiểu tích hợp cho Lớp dữ liệu Acess của bạn, đó là, Tích hợp kiểm tra (= tích hợp Mã lớp truy cập dữ liệu của bạn với DB) bằng cách sử dụng các tính năng của Khung kiểm tra đơn vị. Ví dụ, trong một dự án Spring bạn có thể sử dụng Spring Testcontext để bắt đầu bối cảnh Spring của bạn bên trong một bài kiểm tra đơn vị, và sau đó kết nối với một cơ sở dữ liệu thực và kiểm tra các truy vấn trả về các kết quả chính xác. Quay lại đầu trang Cung cấp Phản hồi THÔNG TIN THÊM Bạn có thể cần một cơ sở dữ liệu riêng cho các bài kiểm tra đơn vị, hoặc có lẽ bạn có thể kết nối chúng với một nhà phát triển DB.

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