c# - Assert if two different objects have same values in a dynamic collection -
i've run rather odd problem xunit.net when comparing 2 objects in dynamic collection (the viewbag).
i have actionfilter following method:
public void onactionexecuting(actionexecutingcontext filtercontext) { var selectlist = new list<selectlistitem>(); var foos = _repo.get(); foreach (var foo in foos) { var selectitem = new selectlistitem() { text = foo.text, value = foo.value }; selectlist.add(selectitem); } filtercontext.controller.viewbag.selectlist = selectlist; }
note how values wrapped in list<selectlistitem>
, assigned viewbag
.
then have test tests if values repository added viewbag:
public void mytest() { // arrange var fakecontroller = substitute.for<controller>(); var fakecontext = substitute.for<actionexecutingcontext>(); fakecontext.controller = fakecontroller; var repository = substitute.for<irepository<foo>>(); var foo = new foo() {text = "foo", value = "bar"}; var foos = new list<foo> { foo }; repository.get().returns(foos); var filter = new myfilter(repository); // act filter.onactionexecuting(fakecontext); // assert var expected = new list<selectlistitem> {new selectlistitem {text = foo.text, value = foo.value}}; assert.equal(expected, fakecontext.controller.viewbag.selectlist); // fails }
this test fails
result message:
assert.equal() failureexpected: list [selectlistitem { disabled = false, group = null, selected = false, text = "foo", value = "bar" }]
actual: list [selectlistitem { disabled = false, group = null, selected = false, text = "foo", value = "bar" }]
to me looks equal.
just in case tested if unexpectedly checking if same instance. below passes. that's not case.
var = new {a = "a"}; var b = new {a = "a"}; assert.equal(a, b); // pass
assert.equal call object's "equals" method. list, inherited object, reference types tests instance equality (i.e.. same instance).
instead, try enumerable.sequenceequal (see here )
updated include implementation of equalitycomparer:
// custom comparer selectlistitem class class selectlistitemcomparer : iequalitycomparer<selectlistitem> { // products equal if names , product numbers equal. public bool equals(selectlistitem x, selectlistitem y) { //check whether compared objects reference same data. if (object.referenceequals(x, y)) return true; //check whether of compared objects null. if (object.referenceequals(x, null) || object.referenceequals(y, null)) return false; //check whether products' properties equal. return x.text.equals(y.text) && x.value.equals(y.value); } // if equals() returns true pair of objects // gethashcode() must return same value these objects. public int gethashcode(selectlistitem item) { //check whether object null if (object.referenceequals(item, null)) return 0; //get hash code name field if not null. int hashtext = item.text == null ? 0 : item.text.gethashcode(); //get hash code code field. int hashvalue = item.value.gethashcode(); //calculate hash code product. return hashtext ^ hashvalue; } }
then can do:
// assert var expected = new list<selectlistitem> {new selectlistitem {text = "this", value = "that"}}; var actual = new list<selectlistitem> {new selectlistitem {text = "this", value = "that"}}; assert.istrue(expected.sequenceequal(actual, new selectlistitemcomparer()));
Comments
Post a Comment