2010-01-04 24 views
5

Trong thử nghiệm đơn vị C# của tôi, tôi thường truy vấn danh sách các hàng dựa trên danh sách ID. Sau đó tôi muốn đảm bảo rằng 1) cho tất cả các ID, có ít nhất một hàng được tìm thấy có ID đó và 2) cho tất cả các hàng được trả về, mỗi hàng có một ID nằm trong danh sách ID để tìm. Dưới đây là cách tôi thường đảm bảo rằng:so sánh danh sách hai chiều trong thử nghiệm đơn vị C#

Tôi nghĩ rằng việc sử dụng các AnyAll thuận tiện cho việc kiểm tra như vậy, nhưng tôi muốn xem có ai nghĩ đây là ít có thể đọc hơn nó có thể được, hoặc nếu có có lẽ một cách tốt hơn để thực hiện kiểm tra hai chiều như thế này. Tôi đang sử dụng MSTest trong Visual Studio 2008 Team System để kiểm tra đơn vị. Điều này có lẽ nên là cộng đồng wiki nếu nó quá chủ quan.

Edit: bây giờ tôi đang sử dụng một giải pháp dựa trên gợi ý Aviad P., và cũng thực tế là thử nghiệm sau đi:

string[] ids1 = { "a", "b", "c" }; 
string[] ids2 = { "b", "c", "d", "e" }; 
string[] ids3 = { "c", "a", "b" }; 
Assert.AreEqual(
    1, 
    ids1.Except(ids2).Count() 
); 
Assert.AreEqual(
    2, 
    ids2.Except(ids1).Count() 
); 
Assert.AreEqual(
    0, 
    ids1.Except(ids3).Count() 
); 

Trả lời

4

Bạn có thể chọn để sử dụng các nhà điều hành Except:

var resultIds = results.Select(x => x[primaryKey]); 

Assert.IsTrue(resultIds.Except(ids).Count() == 0, 
"Returned results had unexpected IDs"); 

Assert.IsTrue(ids.Except(resultIds).Count() == 0, 
"Not all IDs were found in returned results"); 
+0

Điều này có vẻ tốt, và tôi thích cách tôi sẽ viết 'x [primaryKey]' chỉ một lần. Tuy nhiên, tôi nghĩ rằng nó nên là 'Count() == 0', xem xét như thế nào' Ngoại trừ' được mô tả. –

+0

Trên thực tế, bạn cần giữ lại> 0, nhưng trao đổi các tin nhắn xung quanh. Đã sửa đổi câu trả lời của tôi. –

+0

Tại sao bạn cần '> 0'? Tôi hy vọng không có sự khác biệt nào giữa danh sách ID kết quả được truy xuất và danh sách ID mà tôi truy vấn. Intellisense mô tả 'Ngoại trừ' khi tạo ra "sự khác biệt thiết lập của hai chuỗi". –

3

IMO, không phải là có thể đọc được vì nó có thể là . Tạo và viết một phương thức trả về true/false. Sau đó gọi Assert.IsTrue (phương thứcWithDescriptiveNameWhichReturnsTrueOrfalse(), "lý do thất bại");

+2

+1 Đây là bản chất * Tùy chỉnh xác nhận * Mô hình thử nghiệm xUnit, mặc dù bạn cũng có thể biến nó thành phương thức trống và di chuyển xác nhận vào phương thức. –

0

NUnit có gia đình CollectionAssert của khẳng định đó giúp dễ đọc.

1

Dưới đây là một đoạn mã tôi đã thực hiện để đối phó với hai enumerables, và ném ngoại lệ trong khi làm bài kiểm tra đơn vị Trong MS thử nghiệm, nó có thể giúp:

Sử dụng

so sánh hai enumerables:

MyAssert.AreEnumerableSame(expected,actual); 

quản lý ngoại lệ

MyAssert.Throws<KeyNotFoundException>(() => repository.GetById(1), string.Empty); 

public class MyAssert 
    { 
     public class AssertAnswer 
     { 
      public bool Success { get; set; } 
      public string Message { get; set; } 
     } 

     public static void Throws<T>(Action action, string expectedMessage) where T : Exception 
     { 
      AssertAnswer answer = AssertAction<T>(action, expectedMessage); 

      Assert.IsTrue(answer.Success); 
      Assert.AreEqual(expectedMessage, answer.Message); 
     } 

     public static void AreEnumerableSame(IEnumerable<object> enumerable1, IEnumerable<object> enumerable2) 
     { 
      bool isSameEnumerable = true; 
      bool isSameObject ; 

      if (enumerable1.Count() == enumerable2.Count()) 
      { 
       foreach (object o1 in enumerable1) 
       { 
        isSameObject = false; 
        foreach (object o2 in enumerable2) 
        { 
         if (o2.Equals(o1)) 
         { 
          isSameObject = true; 
          break; 
         } 
        } 
        if (!isSameObject) 
        { 
         isSameEnumerable = false; 
         break; 
        } 
       } 
      } 
      else 
       isSameEnumerable = false; 

      Assert.IsTrue(isSameEnumerable); 
     } 

     public static AssertAnswer AssertAction<T>(Action action, string expectedMessage) where T : Exception 
     { 
      AssertAnswer answer = new AssertAnswer(); 

      try 
      { 
       action.Invoke(); 

       answer.Success = false; 
       answer.Message = string.Format("Exception of type {0} should be thrown.", typeof(T)); 
      } 
      catch (T exc) 
      { 
       answer.Success = true; 
       answer.Message = expectedMessage; 
      } 
      catch (Exception e) 
      { 
       answer.Success = false; 
       answer.Message = string.Format("A different Exception was thrown {0}.", e.GetType()); 
      } 

      return answer; 
     } 
    } 
Các vấn đề liên quan