Multiple Moq It.Is <string> () Matching Arguments
With Moq, is it permissible to have more than one match argument?
It.Is<string>() In this example, I want the mockMembershipService to return another ProviderUserKey, depending on the Account provided.
mockMembershipService.Setup( x => x.GetUser( It.Is<string>( s => s.Contains("Joe"))) .ProviderUserKey) .Returns("1234abcd"); mockMembershipService.Setup( x => x.GetUser( It.Is<string>( s => s.Contains("Tracy"))) .ProviderUserKey) .Returns("5678efgh"); By default, SetUp assigns a second statement, rather than evaluating it essentially.
Doesn't that bother you? You are trying to make fun of the GetUser method, but you set the Returns property to the return value of this function. You also want to specify a property of the return type based on the bullying method.
Here's a more understandable way:
mockMembershipService.Setup(x => x.GetUser(It.IsAny<string>()) .Returns<string>(GetMembershipUser); Here is a way to create a membership layout:
private MembershipUser GetMembershipUser(string s) { Mock<MembershipUser> user =new Mock<MembershipUser>(); user.Setup(item => item.ProviderUserKey).Returns(GetProperty(s)); return user.Object; } Then you write a way to set this property:
private string GetProperty(string s) { if(s.Contains("Joe")) return "1234abcd"; else if(s.Contains("Tracy")) return "5678efgh"; } If you want to restrict the input to only “Joe” and “Tracy”, you can specify several conditions in It.Is<T>() . Something like
mockMembershipService.Setup(x => x.GetUser(It.Is<String>(s => s.Contains("Joe") || s.Contains("Tracy"))) .Returns<string>(/* Either Bartosz or Ufuk answer */); Forcing a setting causes the previous settings to be canceled.
You can use your argument in a callback:
mockMembershipService.Setup(x => x.GetUser(It.IsAny<string>()).ProviderUserKey).Returns<string>(s => { if(s.Contains("Joe")) return "1234abcd"; else if(s.Contains("Tracy")) return "5678efgh"; }); If it is important for you to assert the passed argument, you need It.Is<string>(...) instead of It.IsAny<string>(...) .
Please check Introduction to Moq> Matching Arguments :
// matching Func<int>, lazy evaluated mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true); // matching ranges mock.Setup(foo => foo.Add(It.IsInRange<int>(0, 10, Range.Inclusive))).Returns(true); // matching regex mock.Setup(x => x.DoSomething(It.IsRegex("[ad]+", RegexOptions.IgnoreCase))).Returns("foo");