如何根据参数的值设置动态返回结果的模拟?

时间:2016-03-18 22:40:29

标签: c# linq unit-testing moq

我正在尝试测试API控制器方法仅返回基于Name Name = FirstName + ' ' + LastName GetUsersByName(name)匹配的用户(加上一些与此无关的其他状态)。

我有一个公开List<UserModel>方法的存储库。我想模拟该存储库方法的设置,该方法将返回包含与某些存根用户列表(this.testUsers)中的名称条件匹配的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() ); 用户。

我尝试了以下内容:

IsAny<string>

但是我不知道如何将Contains子句绑定到我告诉moq匹配的# This file is named passuserstack.py # I call it by typing: python passuserstack.py johndoe # to add a user named johndoe import os import sys os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dmt.settings") from django.contrib.auth.models import User, Group from django.contrib.auth import authenticate, login arg1 = sys.argv[1] def loginuser(myuser=arg1): myuserpw = myuser + 'pw' # Check to see if that user exists if ( User.objects.filter(username=myuser).exists() ): #do nothing mynote = "I am a returning user" else: # create the user mynote = "I am a new user" ur = User.objects.create_user(myuser, 'notkeeping@email.com', myuserpw) ur.is_staff = True ur.save() # assign permissions by assigning to a group gp = Group.objects.get(name='NBI_graph_tool') #gp.user_set.add(ur) # when I uncomment the line just above this, I get the error : # raise AppRegistryNotReady("Models aren't loaded yet.") # django.core.exceptions.AppRegistryNotReady" Models aren't loaded yet. if __name__ == "__main__": loginuser()

这可能吗?我怀疑我需要为IsAny提供一个参数,但我找不到任何类似的例子。

1 个答案:

答案 0 :(得分:1)

是的,这是可能的。您可以使用Returns<string>

  

指定一个函数,用于计算从方法返回的值,检索调用的参数

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) );

长答案

我能够构建一个示例测试来重新创建你想要的东西。

[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; }
    }
}