模拟新的Microsoft Entity Framework Identity UserManager和RoleManager

Dal*_*use 44 c# unit-testing entity-framework moq asp.net-identity

有没有人想出了一个成功的嘲弄解决方案UserManagerRoleManager?我整天都在靠墙打我的头.我想要做的就是模拟对象以使用内存集合而不是命中Entity Framework数据存储.我已经浏览了互联网并尝试了几种使用MOQ的不同方法.

我的印象是新东西更容易测试.我错过了什么吗?

dan*_*wig 37

或者,您可以模拟接受作为参数的IUserStore<TUser>接口UserManager.

var userStore = new Mock<IUserStore<ApplicationUser>>();
var userManager = new UserManager(userStore.Object);
Run Code Online (Sandbox Code Playgroud)

正如@Joe Brunscheon在下面的评论中指出的那样,UserManager检测到对其他接口的支持,例如IUserPasswordStore等.你也可以moq:

var passwordManager = userStore.As<IUserPasswordStore<ApplicationUser>>()
    .Setup(...).Returns(...);
Run Code Online (Sandbox Code Playgroud)

您不必一次性地完成所有这些操作,您可以根据需要测试代码进行操作.实际上,EF用于实现IUserStore的UserStore实现了其他接口,UserManager将进行内部检测以查看是否实现了这些接口,因此支持其他功能.幸运的是,moq允许你模拟一个可以实现许多接口的代理.As<T>().

简而言之,Microsoft.AspNet.Identity确实为您提供了在代码中无需包装的裸装使用所需的一切.只要您使用依赖注入来实例化您的UserManager,您就可以安全地在单元测试中模拟它消耗的接口,并通过某种类型的IUserStore<T>moq 传递它们,这些moq被扩充以支持UserManager内部检测到的其他接口上的方法.


rub*_*ito 27

我喜欢为任何使用asp.net核心的人更新这个问题的解决方案:

    private Mock<UserManager<ApplicationUser>> GetMockUserManager()
    {
        var userStoreMock = new Mock<IUserStore<ApplicationUser>>();
        return new Mock<UserManager<ApplicationUser>>(
            userStoreMock.Object, null, null, null, null, null, null, null, null);
    }
Run Code Online (Sandbox Code Playgroud)

是的,8次null,但到目前为止还没有更优雅的解决方案.如果您对其他参数感兴趣,请查看源代码.

  • ApplicationUser由asp.net核心项目模板创建.如果您没有使用该模板,那么请尝试"IdentityUser",因为这是ApplicationUser从中继承的根类. (2认同)