2012-03-02 52 views
6

Tôi là một nhà phát triển .Net mã hóa trong C#, và tôi đã được giao cho một dự án mà người quản lý của nó muốn nó được kiểm tra kỹ lưỡng, chủ yếu nhấn mạnh sự cô lập sao cho một lỗi logic lý tưởng thất bại thử nghiệm và không có sự phụ thuộc giữa các thử nghiệm.Thử nghiệm đơn vị Thêm/Lấy các cặp phương thức

Hôm nay chúng ta đang thảo luận mô hình thử nghiệm, và những câu dưới đây đã phát sinh:

phép nói rằng chúng tôi có một đối tượng tên là MyHashTable, mà thực hiện:

void Add(string key, string value); 

string GetValue(string key); 

Chúng tôi muốn kiểm tra mỗi của những phương pháp độc lập. Vấn đề chính của khóa học, một cách hợp lý, chúng tôi không thể có được những gì chúng tôi không bao giờ thêm vào, và chúng tôi không thể xác minh một cái gì đó đã được thêm vào mà không nhận được nó. Chúng tôi đã nghe và đọc về stubbing/mocking và các kỹ thuật khác có thể giúp khắc phục vấn đề này, nhưng không thể quyết định giải pháp nào là dễ đọc nhất và có thể bảo trì được.

Vì vậy, tôi yêu cầu lời khuyên/ý tưởng làm thế nào để kiểm tra những phương pháp đó một cách độc lập, và nếu bạn có thể, bao gồm ưu và khuyết điểm cho đề xuất của bạn. Cảm ơn bạn!

+0

Hãy làm rõ, MyHashTable có phải là một đối tượng thuộc loại bạn tự thực hiện và muốn thử nghiệm nội bộ hay chỉ một phiên bản của lớp bạn đang sử dụng "nguyên trạng" và muốn kiểm tra giao diện bên ngoài? –

Trả lời

2

Nếu bạn muốn đạt được hoàn toàn độc lập và cách ly, thì rất có thể bạn sẽ phải để lộ một số nội bộ của MyHashTable. Ví dụ, cơ bản bộ sưu tập mà Add thêm yếu tố để:

public class MyHashTable<TKey, TValue> 
{ 
    internal Dictionary<TKey, TValue> Storage { get; set; } 
    // ... 
} 

Đây không phải là rất đẹp như bạn có thể nhìn thấy, nhưng như tôi đã nói, nó không thể kiểm tra hai phương pháp trong sự cô lập đầy đủ mà không phơi bày một cái gì đó (như bạn đã nhận thấy, đó là phương thức cặp). Bạn có thể tự nhiên cung cấp các cách khác để khởi tạo lớp của bạn, ví dụ như. với hàm tạo bộ sưu tập, nhưng nó chỉ phân bổ vấn đề một bước xa hơn - bạn sẽ cần phải xác minh rằng hàm tạo đã làm việc tốt, và có thể bạn sẽ cần phương thức Get cho ... điều đó đưa bạn trở lại vấn đề ban đầu.

Edit:

Lưu ý rằng tôi không gợi ý internals hở hang/chi tiết thực hiện như là con đường duy nhất để làm theo. Bạn có thể chỉ cần thử nghiệm các phương thức đó cùng nhau (không phải trong thử nghiệm đơn lẻ, nhưng sử dụng một phương pháp khác), có thể chứng minh là giải pháp tốt hơn. Chắc chắn - nếu Add của bạn tại một số điểm không thành công, Get kiểm tra cũng sẽ không thành công. Nhưng sau đó một lần nữa, bạn muốn sửa chữa Add bị hỏng - một khi đó là thực hiện tất cả mọi thứ là trở lại bình thường. Vấn đề tự nhiên nằm ở cách bạn phân biệt xem đó là Add hoặc Get đã bị hỏng - nhưng đó là nơi các thông báo lỗi xác nhận đúng hoặc cảnh báo xác nhận bảo vệ tôi liên kết trong nhận xét có ích.

Sự thật là, đôi khi tách biệt hoàn toàn và cách ly là quá khó khăn để đạt được hoặc đơn giản sẽ cần bạn giới thiệu thiết kế kém. Đó là một trong những lý do họ không bao giờ nên là mục tiêu cuối cùng.

+0

Vì vậy, về cơ bản những phương pháp đó phải được coi là một cặp, và không thể được kiểm tra cách ly với nhau. Bạn có, trong các dự án thử nghiệm của bạn cho phép một nhóm các xét nghiệm phụ thuộc vào nhau và không bị cô lập hoàn toàn? Không cần phải cố định trên khái niệm cách ly, nếu nó có nghĩa là để bắt đầu thêm nội bộ kỳ lạ hoặc các thứ khác mà sẽ chỉ làm cho mã được thử nghiệm ít bảo trì hơn – Eldar

+0

@ user1244563: Vấn đề ở đây là một số thứ không thể kiểm tra được trong sự cô lập hoàn toàn ('' '' '' của bạn là ví dụ hoàn hảo), trừ khi bạn phơi bày thêm một số thông tin về các hoạt động bên trong của chúng (trong trường hợp này - bộ sưu tập chúng hoạt động). Tôi muốn nói rằng nó là khá bình thường để giả định một trong số họ làm việc tại một số điểm và dựa vào đó sau này (Tôi nghĩ rằng bạn có thể quan tâm đến việc kiểm tra [này] (http://stackoverflow.com/q/9018142/343266) [hai ] (http://stackoverflow.com/q/9385715/343266) câu hỏi). –

+0

Tiết lộ các hoạt động bên trong là một cái gì đó tôi không đồng ý với ... không phải vì tôi là một người đàn ông bị đóng gói (nhiều như tôi không phải là một cô lập) nhưng vì một ngày tôi có thể muốn sử dụng, hãy nói, MemCache là của tôi lưu trữ bên trong. Vì vậy, bây giờ tất cả các bài kiểm tra của tôi phải được refactored. Tôi không muốn các bài kiểm tra dựa vào các hoạt động bên trong giống như cách tôi không muốn các máy khách API của tôi chuyển tiếp trên chúng (một thử nghiệm thực sự chỉ là một trình khách API khác). Tôi chỉ làm như vậy khi mã được dự kiến ​​sẽ gọi mã khác (kiểm tra tương tác) bởi vì tôi muốn đảm bảo tách mối quan tâm, để đảm bảo rằng một API được sử dụng khi cần thiết và không có gì khác. – Eldar

0

Tại sao? Mục đích của một thử nghiệm đơn vị là để đảm bảo rằng phương pháp thử nghiệm hoạt động như mong đợi. Không có gì nói rằng bạn không thể sử dụng các phương pháp khác để đảm bảo rằng phương pháp thử nghiệm hoạt động OK.

các xét nghiệm sau đây cũng tốt bởi tôi (đối với việc thực hiện Hashtable)

[Fact] 
public void AddNewItem() 
{ 
    var hashTable = new MyHashTable(); 

    hashTable.Add("hello", "world"); 

    Assert.True(hashTable.Exists("hello")); 
    Assert.Equal("world", hashTable["hello"]); 
} 

[Fact] 
public void AddExistingItem() 
{ 
    var hashTable = new MyHashTable(); 

    hashTable.Add("hello", "world"); 
    hashTable.Add("hello", "realItem"); 

    Assert.Equal("realItem", hashTable["hello"]); 
} 

Bạn có thể dĩ nhiên thoát ra khỏi lưu trữ bên trong vào một giao diện và tiêm nó trong một constructor:

public class MyHashTable 
(
    public MyHashTable(IKeyValueStorage storage) 
    {} 

    // creates a default storage class 
    public MyHashTable() 
    {} 
) 

Cho phép bạn giả lập bộ nhớ và do đó thử nghiệm một phương thức duy nhất tại một thời điểm. Nhưng điều đó chỉ di chuyển vấn đề thêm một bước nữa. bạn sẽ thử nghiệm triển khai bộ nhớ như thế nào?

Điều tôi đang nói là HashTable là một đơn vị nhỏ bị cô lập. Nó là tốt để kiểm tra nó bằng cách sử dụng phương pháp của nó. Bạn sẽ không gặp vấn đề đó với các mô hình miền vì bạn có thể giả lập các phụ thuộc của chúng.

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