I'm trying to test that an API controller method only returns users (plus some additional states which aren't relevant here) which match based on Name
where Name = FirstName + ' ' + LastName
.
I have a repository which exposes a GetUsersByName(name)
method. I want to mock up a setup for that repository method which will return a List<UserModel>
containing users which match the name criteria from some stubbed list of users (this.testUsers
).
I've tried the following:
this.mockUserReposiotry.Setup(r => r.GetAllUsersByName(It.IsAny<string>()))
.Returns(this.mockUtilities.MockUpUserModel(this.testUsers).Where(u => string.Concat(
u.firstName, " ", u.lastName)
.ToLower().Contains() );
but I don't know how to tie the Contains clause back to the IsAny<string>
that I'm telling moq to match on.
Is this possible? I suspect that I need to provide IsAny with a parameter, but I can't find any similar examples.
Yes it is possible. You can use Returns<string>
which
Specifies a function that will calculate the value to return from the method, retrieving the arguments for the invocation
this.mockUserReposiotry.Setup(r => r.GetAllUsersByName(It.IsAny<string>()))
.Returns<string>(originalParameter => this.mockUtilities.MockUpUserModel(this.testUsers).Where(u => string.Concat(
u.firstName, " ", u.lastName)
.ToLower().Contains(originalParameter) );
Long Answer
I was able to construct an example test to recreate what you are after.
[TestClass]
public class DynamicResultsTests {
List<UserModel> testUsers = new List<UserModel>();
string[] names = new[] { "John Doe", "Jane Doe", "Jack Sprat", "John Smith", "Mary Jane" };
[TestInitialize]
public void Init() {
testUsers = names.Select(n => {
var tokens = n.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
return new UserModel { firstName = tokens[0], lastName = tokens[1] };
}).ToList();
}
[TestMethod]
public void Test_ShouldDynamicallyReturnResultsBasedOnParameterValue() {
//Arrange
string parameterValue = "john";
Func<string, UserModel, bool> predicate = (s, u) => string
.Join(" ", u.firstName, u.lastName)
.IndexOf(s, StringComparison.InvariantCultureIgnoreCase) > -1;
Func<string, List<UserModel>> valueFunction = s =>
this.testUsers.Where(u => predicate(s, u)).ToList();
var mockUserRepository = new Mock<IUserRepository>();
mockUserRepository
.Setup(r => r.GetAllUsersByName(It.IsAny<string>()))
.Returns<string>(valueFunction);
var repository = mockUserRepository.Object;
//Act
var users = repository.GetAllUsersByName(parameterValue);
//Assert (There should be 2 results that match john)
users.Should().NotBeNull();
users.Should().NotBeEmpty();
users.Count().Should().Be(2);
}
public interface IUserRepository {
List<UserModel> GetAllUsersByName(string name);
}
public class UserModel {
public string firstName { get; set; }
public string lastName { get; set; }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With