如何为moq中的属性赋值?

我有一个类的方法,返回一个Usertypes的对象

 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是一个域对象。 注意setterId属性为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是受保护的,因为它是由数据库生成的。

testing项目

在我的testing项目中,我有一个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来创build一个User
这样,我所要做的就是模拟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”创build一个用户时,用户将返回Mock填充;

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

问题是电子邮件,名称,密码是空的(使用默认值)!

在这里输入图像说明

你准备嘲笑的用户的方式是问题。

 moqUser.Object.Name = username; 

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

 moqUser.SetupAllProperties(); 

这个方法将准备模拟的所有属性,以便能够logging分配的值,并在以后重放(即充当不动产)。

您还可以使用SetProperty()方法来设置单个属性,以便logging传入的值。

另一种方法是:

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

我想你错过了嘲笑的目的。 嘲笑用来模拟你正在testing的类的依赖关系:

在这里输入图像说明

被测系统(SUT)应该被隔离testing(即与其他单元分开)。 否则,依赖项中的错误会导致SUTtesting失败。 你也不应该为嘲笑写testing。 这不会给你什么,因为嘲笑不是生产代码。 嘲笑不会在您的应用程序中执行。

所以,只有在testing某个依赖于它的单元时,才应该模拟CustomMembershipProvider (顺便说一下,最好创build一些像ICustomMembershipProvider接口ICustomMembershipProvider抽象方法)。

或者,如果您正在编写CustomMembershipProvider类的testing,那么它不应该被嘲笑 – 只应该嘲笑这个提供者的依赖关系。