2011-11-17 26 views
12

Tôi hiện đang phát triển trình bao bọc C# P/gọi hàm DLL là một phần của sản phẩm của tôi. Tôi không có kinh nghiệm với C# và đây là lần đầu tiên C# mã hóa tôi đã thực hiện. Tôi nhận thức sâu sắc rằng tôi thiếu kiến ​​thức về những điểm tốt hơn và thành ngữ của ngôn ngữ.Làm cách nào để mở rộng lớp NUnit Assert bằng cách thêm một quá tải tĩnh mới cho AreEqual?

Câu hỏi của tôi liên quan đến các bài kiểm tra đơn vị mà tôi đang viết mà tôi đang sử dụng NUnit. Tôi cần phải so sánh các giá trị của các biến số double[]. Nếu tôi sử dụng Assert.AreEqual(...) để làm điều này thì các giá trị được so sánh với sự bình đẳng chính xác. Tuy nhiên, tôi muốn so sánh với sự khoan dung. Có quá tải AreEqual() cho các giá trị thực vô hướng thừa nhận thông số delta. Tuy nhiên, tôi đã không thể tìm thấy một tương đương cho mảng. Tôi đã bỏ lỡ một cái gì đó hiển nhiên?

Tại thời điểm này tôi đã giải quyết được vấn đề với đoạn mã sau:

class Assert : NUnit.Framework.Assert 
{ 
    public static void AreEqual(double[] expected, double[] actual, double delta) 
    { 
     AreEqual(expected.Length, actual.Length); 
     for (int i = 0; i < expected.Length; i++) 
     { 
      AreEqual(expected[i], actual[i], delta); 
     } 
    } 
} 

Trong khi điều này dường như làm việc Tôi tự hỏi nếu có một giải pháp sạch hơn có sẵn. Đặc biệt, tôi lo ngại rằng việc sử dụng cùng tên cho lớp dẫn xuất của tôi là, không chỉ phong cách nghèo nàn, mà còn có thể dẫn đến những vấn đề không lường trước được trên đường.

Tôi muốn sử dụng các phương pháp mở rộng nhưng tôi hiểu rằng chúng chỉ khả thi khi có trường hợp của lớp đang được gia hạn. Tất nhiên, tôi chỉ gọi phương thức tĩnh trên lớp Assert.

Tôi xin lỗi nếu điều này có vẻ hơi mơ hồ, nhưng bản năng của tôi nói với tôi rằng tôi không làm điều này một cách tốt nhất và tôi muốn biết cách làm đúng.

+1

Bạn đã thử [Phương pháp Extension] (http://msdn.microsoft.com/en-us/library/bb383977.aspx)? –

+5

@Ofer Zelig trong khi tôi đã cho bạn +1 tôi nhớ rằng Phương thức mở rộng, trong khi được xác định tĩnh, chỉ hoạt động trên các phiên bản. – dowhilefor

+0

Vì vậy, như nó có vẻ bây giờ, mà không thể được thực hiện (trừ khi bạn đang thực hiện lớp wrapper, rất nhiều công việc khó khăn và xấu xí). Xem [this] (http://stackoverflow.com/questions/249222/can-i-add-extension-methods-to-an-existing-static-class/435617#435617) và [this] (http: // madprops.org/blog/static-extension-methods/). –

Trả lời

7

Kể từ sự ra đời của cú pháp khẳng định thông thạo NUnit, phương pháp Within() đã sẵn sàng cho mục đích này:

double actualValue = 1.989; 
double expectedValue = 1.9890; 
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(0.00001)); 
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(1).Ulps); 
Assert.That(actualValue, Is.EqualTo(expectedValue).Within(0.1).Percent); 

Đối với các bộ sưu tập, hành vi mặc định của Is.EqualTo() là so sánh các thành viên của các bộ sưu tập cá nhân, với những so sánh riêng lẻ này được sửa đổi bởi Within(). Do đó, bạn có thể so sánh hai mảng của đôi như vậy:

var actualDoubles = new double[] {1.0/3.0, 0.7, 9.981}; 
var expectedDoubles = new double[] { 1.1/3.3, 0.7, 9.9810}; 
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(0.00001)); 
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(1).Ulps); 
Assert.That(actualDoubles, Is.EqualTo(expectedDoubles).Within(0.1).Percent); 

này sẽ so sánh mỗi phần tử của actualDoubles tới phần tử tương ứng trong expectedDoubles sử dụng dung sai quy định, và sẽ thất bại nếu có không đủ chặt chẽ.

+0

Cảm ơn rất nhiều vì điều này. Có vẻ như đó là cách tôi mong đợi để giải quyết vấn đề. Tôi đánh giá cao thời gian của bạn ở đây. Cảm ơn bạn rất nhiều. Như một vấn đề về sở thích cá nhân, tôi thấy những giao diện thông thạo này hơi đục. Một khi bạn đã viết nó xuống, nó là loại có ý nghĩa, nhưng bạn phải crack mã để viết nó lần đầu tiên! –

+1

Tôi nghĩ rằng thủ thuật với giao diện thông thạo của loại này là 'phát triển theo hướng chấm'. Nếu bạn đang sử dụng một IDE như Visual Studio, bạn chỉ cần biết 'liên kết đầu tiên trong chuỗi', ví dụ: 'Is', sau đó bạn có thể nhấn' .' và Intellisense sẽ cho bạn thấy tất cả các tùy chọn cho 'bước tiếp theo' của bạn. Tôi đã học về nhiều tính năng như 'Trong()' theo cách đó, thay vì đọc các tài liệu NUnit. – Peter

2

Tôi nghĩ rằng những gì tôi đã có thể làm chỉ đơn giản là định nghĩa một hàm ở đâu đó trong khai thác thử nghiệm của bạn

public static bool AreEqual(double[], double[], double delta)

mà không so sánh và trả về đúng hay sai một cách thích hợp. Trong Bài kiểm tra, bạn chỉ cần viết:

Assert.IsTrue(AreEqual(expected, result, delta)) ; 
+0

Cảm ơn vì điều này. Đó chắc chắn là một ý tưởng hay. Nhược điểm đối với tôi là tôi thấy rằng khi tôi cố gắng thực hiện điều này, tôi đã phải thực hiện lại so sánh 'delta' đi kèm miễn phí khi bạn gọi AreEqual với đầu vào vô hướng thực. Vì vậy, câu trả lời của @dowhilefor dường như phù hợp với nhu cầu của tôi tốt hơn thời gian này. Cám ơn vì đã quan tâm! –

2

"Tốt hơn" luôn là vấn đề về hương vị. Trong trường hợp này, tôi sẽ nói có. Bạn nên làm cho khẳng định của riêng bạn, mà không có phân lớp các khẳng định nunit. Nunit đã có nhiều lớp Assert với các xác nhận cụ thể khác nhau. Giống như CollectionAssert. Nếu không phương pháp của bạn là tốt.

+0

Cảm ơn vì điều này. Tôi đã không phát hiện ra các lớp 'XXXAssert' khác. Vì vậy, tôi đã thêm một lớp 'ArrayAssert' và di chuyển mã của tôi trong đó. Nó cảm thấy khá tự nhiên bây giờ và vibes xấu của tôi đã rút đi. –

2

Tôi có nhu cầu tạo xác nhận tùy chỉnh, trong trường hợp của bạn có một thay thế do khung công tác cung cấp. Tuy nhiên điều này không hiệu quả khi tôi muốn có một khẳng định hoàn toàn tùy chỉnh. Tôi giải quyết điều này bằng cách thêm một lớp tĩnh mới gọi vào nunit.

public static class FooAssert 
{ 
    public static void CountEquals(int expected, FooConsumer consumer) 
    { 
     int actualCount = 0; 
     while (consumer.ConsumeItem() != null) 
      actualCount++; 

     NUnit.Framework.Assert.AreEqual(expected, actualCount); 
    } 
} 

Sau đó, trong một thử nghiệm

[Test] 
public void BarTest() 
{ 
    // Arrange 
    ... 

    // Act 
    ... 

    // Assert 
    FooAssert.CountEquals(1, fooConsumer); 
} 

Tôi biết tôi là một chút trễ cho bữa tiệc, nó vẫn có thể có ích cho ai đó

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