You can use Arg<T>.Matches
:
myMock.Expect(x => x.MyMethod(Arg<IEnumerable<string>>.Matches(s => !s.Except(expected).Any() && !expected.Except(s).Any()));
문제
I'm writing a unit test, I want to ensure that a particular method is called with some parameters:
var myMock = MockRepository.GenerateMock<IMyService>();
IMyService has a method on it with the signature
public bool SomeMethod(IEnumerable<string> values)
I have a business logic layer which consumes my mock
public class BusinessLogic
{
protected MyMock MyMock{get;set;}
public BusinessLogic (myMock)
{
this.MyMock = myMock;
}
public bool DoLogic()
{
var myCollection = // loaded from somewhere
return this.MyMock(myCollection);
}
}
I want to test the DoLogic method by making sure that it calls SomeMethod properly. However I have no control (and don't really want it over the ordering of the collection).
I want to assert that the method SomeMethod
is called with the IEnumerable {"a", "b", "c"}
but I don't care on the order.
So far I have
myMock.Expect(x => x.MyMethod(new string[]{"a", "b", "c"});
and
myMock.AssertWasCalled(x => x.MyMethod(new string[]{"a", "b", "c"});
But this will fail if it's called with {"b", "a", "c"}
. I don't want to change my business logic to ensure the ordering of the parameters (as this would design the BLL around the tests).
How can I assert this method call?
해결책
You can use Arg<T>.Matches
:
myMock.Expect(x => x.MyMethod(Arg<IEnumerable<string>>.Matches(s => !s.Except(expected).Any() && !expected.Except(s).Any()));
다른 팁
Test frameworks usually have assertions for such matching, you can mix those two. Example with NUnit's EquivalentTo
:
myMock.Expect(x => x.MyMethod(Arg<IEnumerable<string>>.Matches(value =>
{
Assert.That(value, Is.EquivalentTo(new[] { "c", "b", "a" }));
return true;
}));
This way, produced error message should be more descriptive than what Rhino will generate.