2009-10-02 44 views
10

Hãy nói rằng tôi ví dụ có lớp này mà tạo ra con số Fibonacci:C#: Bạn kiểm tra phương thức IEnumerable.GetEnumerator() như thế nào?

public class FibonacciSequence : IEnumerable<ulong> 
{ 
    public IEnumerator<ulong> GetEnumerator() 
    { 
     var a = 0UL; 
     var b = 1UL; 
     var c = a + b; 
     while (true) 
     { 
      yield return c; 
      c = a + b; 
      a = b; 
      b = c; 
     } 
    } 
    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

Sau đó tôi có thể viết một bài kiểm tra đó đảm bảo rằng các n số đầu tiên trong dãy là chính xác.

[Test] 
    public void GetEnumerator_FirstFifteenNumbers_AreCorrect() 
    { 
     var sequence = new FibonacciSequence().Take(15).ToArray(); 
     CollectionAssert.AreEqual(sequence, new[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}); 
    } 

Khi tôi kiểm tra bảo hiểm, tôi sẽ thấy rằng phương thức IEnumerable.GetEnumerator() chưa được kiểm tra và mức độ phù hợp của tôi sẽ thấp hơn mức cần thiết. Đủ công bằng. Nhưng làm thế nào tôi nên kiểm tra phương pháp đó?

Bạn thường xử lý vấn đề này như thế nào?

+0

hmm, ngoài sự tò mò làm thế nào để bạn kiểm tra phạm vi kiểm tra? Âm thanh như một tính năng thú vị. – Ian

+1

Vâng, tôi cũng tự hỏi về điều đó, hehe. Nhưng tìm thấy một nút cho nó trong TestDriven.Net, đó là khá awesome bằng cách này. Nếu bạn chưa thử nó, bạn nên! Sau khi cài đặt, bạn có thể nhấp chuột phải vào giải pháp của bạn (trong trình khám phá giải pháp) và chọn Kiểm tra với -> Mức độ phù hợp. Dễ dàng như vậy :) – Svish

+0

Nếu bạn có phiên bản VS Team System, các công cụ kiểm tra bao gồm một công cụ bảo hiểm là tốt, mà bạn có thể kích hoạt với TestDriven.Net hoặc trong giao diện thường xuyên. Nếu không, nếu bạn google kiểm tra các công cụ bảo hiểm cho Visual Studio, có một số ra khỏi đó. NCover có thể được sử dụng nhiều nhất. – McMuttons

Trả lời

11

EDIT: Cập nhật dựa trên những gì Marc nói.

Vâng, bạn có thể có được bảo hiểm lên bằng cách thực hiện:

// Helper extension method 
public static IEnumerable AsWeakEnumerable(this IEnumerable source) 
{ 
    foreach (object o in source) 
    { 
     yield return o; 
    } 
} 

... 

[Test] 
public void GetEnumerator_FirstFifteenNumbers_AreCorrect() 
{ 
    IEnumerable weak = new FibonacciSequence().AsWeakEnumerable(); 
    var sequence = weak.Cast<int>().Take(15).ToArray(); 
    CollectionAssert.AreEqual(sequence, 
     new[] {1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}); 
} 

Lưu ý rằng weak được khai báo là nongeneric IEnumerable loại ... có nghĩa là bạn cần phải gọi Cast vào nó để đúc từng trở lại đối tượng int.

Tôi không chắc chắn mình sẽ bận tâm ...

+1

Không - tôi đã kiểm tra, và 'Cast ' thực sự kiểm tra thông qua 'as' cho' IEnumerable ', vì vậy bạn sẽ sử dụng' IEnumerable .GetEnumerator() ', không phải là IEnumerable.GetEnumerator()' –

+0

Đó là những gì tôi thấy. Vì vậy, sau đó tôi đã không hoàn toàn chắc chắn làm thế nào để đi về làm việc đó, hehe. – Svish

+0

Cố định, nhờ guys - đó là một trường hợp gói phiên bản mạnh mẽ trong các yếu ... –

3

Bạn sẽ phải sử dụng số IEnumerable (không chung); Tôi gửi bài trả lời sử dụng Cast<T>, nhưng điều đó vẫn sẽ lừa gạt (nó kiểm tra cho các loại hình mong muốn là một trường hợp đặc biệt) - bạn có thể cần một cái gì đó như:

public static int CountUntyped(this IEnumerable source) { 
    int count = 0; 
    foreach(object obj in source) { count++; } 
    return count; 
} 

IEnumerable<T> source = ... 
Assert.AreEqual(typed.Count(), source.CountUntyped()); 
+1

Nhưng điều đó sẽ chỉ so sánh số lượng vật phẩm trong số đếm, đúng không? Và điều đó sẽ có tác dụng xấu trong trường hợp của tôi, vì FibonacciSequence không bao giờ thực sự kết thúc: p – Svish

+0

Lol! Vâng, tôi lấy ý kiến ​​của bạn ở đó. Nhưng điều tôi đang cố gắng làm nổi bật là làm việc với 'IEnumerable' thay vì 'IEnumerable ' - và tôi không nghĩ rằng bạn có thể đơn giản sử dụng 'Cast ',' cos ... –

4

Tôi sẽ không kiểm tra. Tôi sẽ cố gắng lọc phương pháp ra khỏi công cụ bảo hiểm. Tôi nghĩ rằng bảo hiểm nên kiểm tra những điều tôi muốn có bảo hiểm và không phải tất cả mọi thứ. Từ ý kiến ​​khác bạn dường như đang sử dụng TestDriven.Net. Tôi không biết làm thế nào tốt mà các bộ lọc nhưng nó đã có thể với NCover. Bạn cũng có thể thử PartCover.

+0

Tất nhiên, và tôi không đánh bại bản thân mình lên trên này hoặc bất cứ điều gì. Chỉ cần tò mò để xem làm thế nào những người khác đối phó với nó :) – Svish

+0

@Svish - xin lỗi, câu trả lời âm thanh đoạn hơn tôi dự định. Nhưng tôi thực sự sẽ xem xét lọc mọi thứ. Tôi nghĩ rằng nó là tốt hơn so với cố gắng để thêm một thử nghiệm cho nó. –

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