2011-11-22 39 views
7

Tôi muốn kiểm tra một đoạn mã trả về một đối tượng.Kiểm thử đơn vị ... cách cải thiện nó

tôi sử dụng NUnit và trong một lớp học kiểm tra, tôi viết một phương pháp để kiểm tra xem phương pháp của tôi hoạt động tốt ...

[Test] 
public void GetMyObjectFromLog() 
{ 
    string _xmlFilePath = @"C:\XmlFile.xml"; 
    MyObjectParser _myObjectParser = new MyObjectParser(); 
    MyObject _mockMyObject = new MyObject 
           { 
            Title = "obj", 
            Name = "objName" 
           } 
    MyObject _myObject = _myObjectParser.GetMyObjectFromLog(_xmlFilePath); 

    Assert.AreEqual(_mockMyObject , _myObject); 
} 

thử nghiệm này không làm việc vì MyObject không ghi đè Equals phương pháp, và tôi don không muốn ghi đè phương thức Equals chỉ nhằm mục đích kiểm tra.

Vì vậy, tôi viết lại bài kiểm tra như thế này:

[Test] 
public void GetMyObjectFromLog() 
{ 
    string _xmlFilePath = @"C:\XmlFile.xml"; 
    MyObjectParser _myObjectParser = new MyObjectParser(); 
    MyObject _myObject = _myObjectParser.GetMyObjectFromLog(_xmlFilePath); 

    Assert.AreEqual("obj", _myObject.Title); 
    Assert.AreEqual("objName", _myObject.Name); 
} 

Ok, nó hoạt động ... nhưng thử nghiệm này là thích hợp? Hơn nữa, có một sự phụ thuộc vào một tập tin.

Có phù hợp để sử dụng khung Mock thay vì không? Và làm thế nào để sử dụng nó?

Cảm ơn bạn!

+0

Thực tế, bạn có thể viết thư từ theo một dòng, nhưng nó có khả năng đọc kém: 'Assert.That (myObjectA, Is.EqualTo (myObjectB) .Sử dụng ((x, y) => x.Name == y .Name && x.Title == y.Title? 0: 1)); ' – Restuta

Trả lời

1

ok hoàn toàn của nó để có tham chiếu đến tệp. Nói chung có hai loại thử nghiệm: kiểm tra đơn vị và thử nghiệm tích hợp.

Kiểm tra tích hợp luôn tương tác với một số tệp/cơ sở dữ liệu hoặc bao giờ. Trong trường hợp của bạn, bạn có thể cải thiện thử nghiệm bằng cách chế nhạo _myObjectParser.GetMyObjectFromLog.

Bạn có thể tự mình viết mô hình hoặc sử dụng khung làm việc như tê giác. Một cuốn sách rất hay cho nunit/rhinomocks là: Nghệ thuật kiểm thử đơn vị.

Một phiên bản thể kiểm chứng tốt hơn về GetMyObjectFromLog có thể trông như thế này:

public MyObject GetMyObjectFromLog(IMyXmlReader reader) 
{ 
    var xmlData = reader.GetData(); 
    //make your object here 
    var obj = new MyObject(xmlData); 
    return obj; 
} 

Sau đó bạn có thể thực hiện 2 lớp mới mà implemments một Interface IMyXmlReader, một mà đọc từ một tập tin mã hiệu của bạn, và một trong đó trả về luôn luôn là cùng một chuỗi trên GetData().

Sau đó, bạn có thể sử dụng Lớp của mình để luôn trả về một chuỗi tĩnh cho các bài kiểm tra đơn vị của bạn.

Hiểu không? Xin lỗi vì tiếng anh của tôi :)

+1

Chúa Giêsu ... tại sao tôi nên thêm các giải pháp để ngăn xếp tràn nếu một số người luôn đá nó xuống. Tôi không thích điều đó – Grrbrr404

+0

Lol. Anh ấy cũng bình chọn cho tôi. Bạn cố gắng giúp đỡ và đó là những gì bạn nhận được :) –

+0

Và câu hỏi nhận được 3 phiếu lol. –

1

Có vẻ như ok. Tuy nhiên, bạn có thể ghi đè Equals trong dự án thử nghiệm của mình, nếu bạn không cần nó trong dự án chính của mình. Ví dụ. thông thường tôi tạo ra các lớp học thúc đẩy các lớp học tư nhân và bảo vệ cho các lớp học công cộng. Vì vậy, bạn được miễn phí để mở rộng dự án chính của bạn để chỉ đơn giản là thử nghiệm trong dự án thử nghiệm của bạn.

Phụ thuộc vào tệp là ok, chỉ cần đặt tệp này trong dự án bộ thử nghiệm của bạn.

0

Mục đích của kiểm tra đơn vị là để kiểm tra logic của mã, thử nghiệm của bạn ở trên đang làm hai điều: 1. logic 2. Tìm kiếm

tôi nói tìm kiếm bởi vì bạn đang cố gắng để phù hợp với một đối tượng mà bạn đã tạo trong một tệp bên ngoài. Nếu bạn làm điều đó vấn đề là xây dựng của bạn sẽ bắt đầu phá vỡ nếu không có tập tin bên ngoài hiện tại và bạn không muốn điều đó.

Giải pháp: Tạo tệp khi di chuyển nhưng không tạo tệp vật lý, tạo Tệp trong bộ nhớ rồi chèn đối tượng bạn cần khớp, sau đó đối sánh đối tượng.

Bằng cách này, thử nghiệm này sẽ không bao giờ bị hỏng.

+0

Tại sao bạn lại bỏ phiếu này? –

+1

Tôi đã không downvote này, nhưng câu trả lời của bạn không có ý nghĩa - bạn không thể tạo một tập tin trong bộ nhớ. Tệp là một lớp tĩnh. Ý bạn là Luồng? –

2

Về rằng sự phụ thuộc vào các tập tin (mà thậm chí dường như không có trong dự án!):

Bạn có thể ghi đè lên rằng _myObjectParser.GetMyObjectFromLog để cũng chấp nhận một Stream. Sau đó, bạn có thể thêm tệp XML đó dưới dạng tài nguyên nhúng và đọc nó từ assembly.

5

Trước hết, phương thức bên trong trình phân tích cú pháp phải là tên "Phân tích cú pháp" thay vì "Nhận". Trước hết, nếu bạn không muốn chính đối tượng có thể so sánh chính nó với một đối tượng khác, thì tốt nhất là so sánh chúng giống như bạn đã làm (thuộc tính của thuộc tính). Nhưng điều này có thể được trích xuất thành một phương thức trợ giúp trong lớp thử nghiệm.

Và cuối cùng, bạn không thực sự muốn kết hợp chặt chẽ trình phân tích cú pháp của mình với một tệp. Bạn chỉ muốn phân tích văn bản. Nếu bạn muốn bao gồm một phương thức trợ giúp tĩnh cũng mở ra một tệp và mọi thứ, đó là lựa chọn của bạn, nhưng nó không phải là một sự phụ thuộc cá thể thuần túy.

[Test] 
public void ParsesObjectFromXml() 
{ 
    string xmlInput = " ... "; 
    MyObjectXmlParser parser = new MyObjectXmlParser(); 
    MyObject expected = new MyObject() {Title = "obj", Name="objName"}; 

    AssertMyObjectsAreEqual(expected, parser.Parse(xmlInput)); 
} 

private bool AssertMyObjectsAreEqual(MyObject expected, MyObject actual) 
{ 
    Assert.AreEqual(expected.Title, actual.Title); 
    Assert.AreEqual(expected.Name, actual.Name); 
} 

Bây giờ cả lớp và bài kiểm tra của bạn đều rõ ràng hơn và chỉ có một trách nhiệm duy nhất.

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