c# - 如何为最小起订量中的属性赋值?

标签 c# unit-testing mocking moq

我有一个类,它有一个返回类型为 User 的对象的方法

public class CustomMembershipProvider : MembershipProvider
{
    public virtual User GetUser(string username, string password, string email, bool isApproved)
    {
        return new User()
            {
                Name = username
                ,Password = EncodePassword(password)
                ,Email = email
                ,Status = (isApproved ? UsuarioStatusEnum.Ativo : UsuarioStatusEnum.ConfirmacaoPendente)
                // ...
            };
    }

    // ..
}

User 是一个域对象。注意 Id 属性,其中 setter protected :

public class User : IAuditable, IUser
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual string Email { get; set; }
    public virtual UsuarioStatusEnum Status { get; set; }
    public virtual string Password { get; set; }
}

Id 是 protected ,因为它是由数据库生成的。

测试项目

在我的测试项目中,我有一个 Fake 存储库,其中包含一个方法 Store 来保存/更新对象:

public void Store(T obj)
{
    if (obj.Id > 0)
        _context[obj.Id] = obj;
    else
    {
        var generateId =  _context.Values.Any() ? _context.Values.Max(p => p.Id) + 1 : 1;
        var stubUser = Mock.Get<T>(obj); // In test, will always mock
        stubUser.Setup(s => s.Id).Returns(generateId);
        _context.Add(generateId, stubUser.Object);
    }
}

CustomMembershipProvider 中,我有 public override MembershipUser CreateUser 方法调用 GetUser 来创建一个 User。< br/> 这样,我所要做的就是模拟 GetUser 方法,以便存储库可以生成 Id

var membershipMoq = new Mock<CustomMembershipProvider>();
membershipMoq.CallBase = true;
membershipMoq
    .Setup(p => p.GetUser(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>()))
    .Returns<string, string, string, bool>( (username, password, email, isAproved) => {
        var moqUser = new Mock<User>();
        moqUser.Object.Name = username;
        moqUser.Object.Password = password;
        moqUser.Object.Email = email;
        moqUser.Object.Status = (isAproved ? UsuarioStatusEnum.Ativo : UsuarioStatusEnum.ConfirmacaoPendente);
        return moqUser.Object;
    });
_membershipProvider = membershipMoq.Object;

问题

理论上一切都是正确的。当CreateUser调用'GetUser'创建用户时,用户将返回Mock filled;

[TestMethod]
public void CreateUser_deve_criar_usuario_no_repositorio()
{
    // Act
    MembershipCreateStatus status;
    var  usr = _membershipProvider.CreateUser(
        _fixture.Create<string>(),
        _fixture.Create<string>(),
        _fixture.Create<string>(),
        null, null, true, null,
        out status);

    // usr should have name, email password filled. But not!

    // Assert
    status.Should().Be(MembershipCreateStatus.Success);
}

问题是 Email, Name, Password 都是空的(有默认值)!

enter image description here

最佳答案

问题在于您准备模拟用户的方式。

moqUser.Object.Name = username;

不会设置名称,除非您已正确设置模拟。 在为属性赋值之前试试这个:

moqUser.SetupAllProperties();

此方法将准备 mock 上的所有属性,以便能够记录分配的值,并在稍后重播(即充当真实属性)。

您还可以使用SetupProperty() 方法来设置各个属性,以便能够记录传入的值。

另一种方法是:

var mockUser = Mock.Of<User>( m =>
    m.Name == "whatever" &&
    m.Email == "someone@example.com"); 

return mockUser;

关于c# - 如何为最小起订量中的属性赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16816551/

相关文章:

c# - 在 WPF 窗口中显示时间

c# - 为什么单独的 DbContexts 在单元测试期间修改同一个 DbSet?

用于属性的 Python mock.patch.object

python - 对使用 requests 库的 python 应用程序进行单元测试

c# - 找不到 View -ASP.NET MVC错误

c# - 使用多线程访问相同的字符串(StringBuilder)

c# - 按升序排列数组的值

php - 在套件中的每个测试之前运行设置代码

delphi - DUnit 无法创建表单。当前没有处于事件状态的 MDI 表单

c++ - 模拟 C++ 标准库