为什么添加操作不适用于 Mock?
Why add operation is not working on a Mock?
所以我再次尝试使用不同的控制器来测试使用 NUnit 和 Moq 的 Cocoa 桌面应用程序。问题是,即使在 .add() 操作之后,我仍然没有使用模拟添加的内容。更准确地说,这就是我进行模拟的方式:
User user = new User
{
email = "test@gmail.com",
password = "1",
firstName = "Test",
lastName = "Test"
};
List<User> dataSource = new List<User>();
var userServiceMock = new Mock<IUserService>(MockBehavior.Strict);
userServiceMock.Setup(x => x.add(It.IsAny<User>()));
userServiceMock.Setup(x => x.getAllUsers()).Returns(dataSource);
var controller = new CreateAccountCoreController(userServiceMock.Object);
//act
controller.submit();
//assert
Assert.That(dataSource.Contains(user));
在控制器中是这样的:
readonly IUserService userService;
public CreateAccountCoreController(IUserService userService)
{
this.userService = userService;
}
public void submit()
{
User user = new User
{
email = "test@gmail.com",
password = "1234",
firstName = "Test",
lastName = "Test",
};
userService.add(user);
List<User> users = userService.getAllUsers();
/*users it is empty here..*/
}
所以我的测试总是失败,因为即使在 .add 操作之后,用户列表还是空的。你能帮忙吗?
没有地方可以让你填充 dataSource
集合,你可以从 getAllUsers()
模拟中将你的模拟配置为 return 它。所以你总是会从一个方法中得到一个空集合。
使用 Callback()
方法配置预期行为:
userServiceMock.Setup(x => x.add(It.IsAny<User>())).Callback((User u) => dataSource.Add(u));
第二个问题可能是在Contains()
方法中比较用户。您需要告诉 Contains
是什么让两个用户相等。默认情况下,它将使用 ReferenceEquals
,如果它们是相同的实例,则只会调用两个对象相等。
在您的用户 class 中覆盖 Equals
和 GetHashCode
或定义 IEqualityComparer<User>
class 并将其传递给 Contains
。
如果两个具有相同 email
的用户是 "equal" 那么实现非常简单:
public override bool Equals(object o)
{
if(o.GetType() != typeof(User))
return false;
return this.email == ((User)o).email;
}
public override int GetHashCode()
{
return email.GetHashCode();
}
您可以阅读有关 value equality for a type 的更多信息。
所以我再次尝试使用不同的控制器来测试使用 NUnit 和 Moq 的 Cocoa 桌面应用程序。问题是,即使在 .add() 操作之后,我仍然没有使用模拟添加的内容。更准确地说,这就是我进行模拟的方式:
User user = new User
{
email = "test@gmail.com",
password = "1",
firstName = "Test",
lastName = "Test"
};
List<User> dataSource = new List<User>();
var userServiceMock = new Mock<IUserService>(MockBehavior.Strict);
userServiceMock.Setup(x => x.add(It.IsAny<User>()));
userServiceMock.Setup(x => x.getAllUsers()).Returns(dataSource);
var controller = new CreateAccountCoreController(userServiceMock.Object);
//act
controller.submit();
//assert
Assert.That(dataSource.Contains(user));
在控制器中是这样的:
readonly IUserService userService;
public CreateAccountCoreController(IUserService userService)
{
this.userService = userService;
}
public void submit()
{
User user = new User
{
email = "test@gmail.com",
password = "1234",
firstName = "Test",
lastName = "Test",
};
userService.add(user);
List<User> users = userService.getAllUsers();
/*users it is empty here..*/
}
所以我的测试总是失败,因为即使在 .add 操作之后,用户列表还是空的。你能帮忙吗?
没有地方可以让你填充 dataSource
集合,你可以从 getAllUsers()
模拟中将你的模拟配置为 return 它。所以你总是会从一个方法中得到一个空集合。
使用 Callback()
方法配置预期行为:
userServiceMock.Setup(x => x.add(It.IsAny<User>())).Callback((User u) => dataSource.Add(u));
第二个问题可能是在Contains()
方法中比较用户。您需要告诉 Contains
是什么让两个用户相等。默认情况下,它将使用 ReferenceEquals
,如果它们是相同的实例,则只会调用两个对象相等。
在您的用户 class 中覆盖 Equals
和 GetHashCode
或定义 IEqualityComparer<User>
class 并将其传递给 Contains
。
如果两个具有相同 email
的用户是 "equal" 那么实现非常简单:
public override bool Equals(object o)
{
if(o.GetType() != typeof(User))
return false;
return this.email == ((User)o).email;
}
public override int GetHashCode()
{
return email.GetHashCode();
}
您可以阅读有关 value equality for a type 的更多信息。