2012-01-25 28 views
8

Tôi muốn "kết hợp" xác nhận thu thập thông tin và xác nhận quyền sở hữu của Thông báo xác thực, ví dụ: khẳng định rằng hai số của IEnumerable tương đương nhau bằng cách sử dụng so sánh thuộc tính theo từng thuộc tính (có thể là "lồng nhau") (nghĩa là sự bình đẳng về cấu trúc, trong ngôn ngữ chức năng).Làm cách nào để kết hợp xác nhận quyền sở hữu bộ sưu tập và thuộc tính bằng cách sử dụng xác nhận thông thạo?

bê tông dụ:

var dic = new Dictionary<int, string>() { {1, "hi"}, {2, "bye" } }; 
var actual = dic.ToSelectListItems(0).OrderBy(si => si.Text); 

var expected = new List<SelectListItem>() { 
    new SelectListItem() {Selected = false, Text="bye", Value="2"}, 
    new SelectListItem() {Selected = false, Text="hi", Value="1"} 
}; 

Ở đây tôi đã viết một phương pháp khuyến nông ToSelectListItems có thể chuyển đổi một Dictionary một IEnumerable của SelectListItem s (từ ASP.NET MVC). Tôi muốn khẳng định rằng actualexpected là "có cấu trúc" bằng nhau, lưu ý rằng loại tham chiếu SelectListItem không ghi đè Equal s và do đó sử dụng bình đẳng tham chiếu theo mặc định.

Cập nhật

Hiện đang sử dụng giải pháp cuộn bằng tay sau, vẫn hy vọng cho một cái gì đó được xây dựng tốt hơn vào FluentAssertions:

public static void ShouldBeStructurallyEqualTo<T, U>(this IEnumerable<T> actual, IEnumerable<U> expected) { 
    actual.Should().HaveCount(expected.Count()); 
    actual.Zip(expected).ForEach(pair => pair.Item1.ShouldHave().AllProperties().IncludingNestedObjects().EqualTo(pair.Item2)); 
} 

(lưu ý: Zip đây là của riêng IEnumerable gia hạn của tôi trong đó sử dụng Tuple.Create như chiếu mặc định)

Cập nhật 2

Dưới đây là hai ví dụ nhỏ:

public class FooBar { 
    public string Foo { get; set; } 
    public int Bar { get; set; } 
} 

public class TestClass { 
    [Test] 
    public void MinimalExample() { 
     List<FooBar> enumerable1 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }; 
     List<FooBar> enumerable2 = new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }; 

     enumerable1.ShouldHave().SharedProperties().IncludingNestedObjects().EqualTo(enumerable2); 

     //Test 'TestClass.MinimalExample' failed: System.Reflection.TargetParameterCountException : Parameter count mismatch. 
     // at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) 
     // at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
     // at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) 
     // at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index) 
     // at FluentAssertions.Assertions.PropertyEqualityValidator.AssertSelectedPropertiesAreEqual(Object subject, Object expected) 
     // at FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker tracker, String parentPropertyName) 
     // at FluentAssertions.Assertions.PropertyEqualityValidator.Validate() 
     // at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject, String reason, Object[] reasonArgs) 
     // at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject) 
     // MiscAssertions.cs(32,0): at TestClass.MinimalExample() 
    } 

    [Test] 
    public void MinimalExample2() { 
     IEnumerable<FooBar> enumerable1 = (new List<FooBar>() { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }).Cast<FooBar>(); 
     FooBar[] enumerable2 = new [] { new FooBar() { Foo = "x", Bar = 1 }, new FooBar() { Foo = "y", Bar = 2 } }; 

     enumerable1.ShouldHave().SharedProperties().IncludingNestedObjects().EqualTo(enumerable2); 

     //Test 'TestClass.MinimalExample2' failed: System.InvalidOperationException : Please specify some properties to include in the comparison. 
     // at FluentAssertions.Assertions.PropertyEqualityValidator.Validate(UniqueObjectTracker tracker, String parentPropertyName) 
     // at FluentAssertions.Assertions.PropertyEqualityValidator.Validate() 
     // at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject, String reason, Object[] reasonArgs) 
     // at FluentAssertions.Assertions.PropertyAssertions`1.EqualTo(Object otherObject) 
     // MiscAssertions.cs(52,0): at TestClass.MinimalExample2() 
    } 
} 

Trả lời

6

Tôi đã thêm hỗ trợ cho kịch bản của bạn trong nhánh chính của Xác nhận thông thạo. Nó sẽ là một phần của phiên bản tiếp theo, nhưng chúng tôi có thể mất một hoặc hai tháng để tích lũy đủ thay đổi để đảm bảo một bản phát hành khác. Nếu bạn muốn, bạn có thể lấy nguồn xây dựng và chạy release.bat để xây dựng một phiên bản trung gian.

+1

Tôi đã sửa cách giải quyết Stephens để làm việc với các kiểu giá trị tốt, nếu T là một kiểu giá trị nó không hoạt động mà không cần sửa lỗi này: https://gist.github.com/1877672 –

+0

Nó nằm trong phiên bản beta công khai của phiên bản 2.0 http : //fluentassertions.codeplex.com/releases/view/82423 –

+3

Và nó được hỗ trợ như thế nào? Tôi không thể tìm thấy một ví dụ tài liệu. – ferpega

7

Nếu tôi giải thích câu hỏi của bạn một cách chính xác, tôi nghĩ bạn nên thử phiên bản 1.7.0 của Khẳng định thạo. Trong phiên bản đó, chúng tôi đã thay đổi hành vi mà khi IncludeNestedObjects được sử dụng, nó cũng sẽ làm điều đó trên các bộ sưu tập các đối tượng. Một đoạn trích của tài liệu.

"Ngoài ra, bạn có thể thực hiện so sánh cấu trúc ở cấp độ cao hơn bằng cách bao gồm thuộc tính IncludeNestedObjects.Điều này sẽ hướng dẫn so sánh so sánh tất cả (tập hợp) loại phức tạp mà thuộc tính của chủ đề (trong ví dụ này) tham chiếu. mặc định, nó sẽ xác nhận rằng các thuộc tính lồng nhau của đối tượng khớp với các thuộc tính lồng nhau của đối tượng mong đợi, tuy nhiên, nếu bạn chỉ định SharedProperties, thì nó sẽ chỉ so sánh các thuộc tính được đặt tên giống nhau giữa các đối tượng lồng nhau. Ví dụ:

dto.ShouldHave().SharedProperties().IncludingNestedObjects.EqualTo(customer); "

+0

Xin chào Dennis, cảm ơn sự quan tâm của bạn. Tôi đang sử dụng 1.7.0, nhưng vấn đề là (sử dụng ví dụ của bạn) 'dto' và' customer' là cả hai lớp con của "IEnumerable <'T>' và do đó không có bất kỳ thuộc tính được chia sẻ nào (các phần tử chúng chứa, nhưng không bản thân IEnumerable). Vì vậy, tôi nhận được 'System.InvalidOperationException: Vui lòng chỉ định một số thuộc tính để bao gồm trong so sánh. tại FluentAssertions.Assertions.PropertyEqualityValidator.Validate (UniqueObjectTracker tracker, String parentPropertyName) ' –

+0

Vì vậy, bạn có nghĩa là cả hai' thực tế' và 'dự kiến' đại diện cho bộ sưu tập đếm với các đối tượng không chính xác giống nhau, nhưng có cùng thuộc tính? –

+0

Chính xác. _ _ _ _ _ _ _ _ –

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