lea*_*arn 2 c# unit-testing moq mocking
我有一个用户界面可以调用它IUser.这有两个实现:AdminUser and NormalUser.
现在,我试图通过单元测试(Mocking)来使用这些用户类.
我按如下方式模拟界面:
var mockUser = new Mock<IUser>();
mockUser.get("username");
Run Code Online (Sandbox Code Playgroud)
我在整个类中添加了breakkpoints,但我不确定接口的哪个实例被调用,即AdminUser or NormalUser.
它永远不会停留在调试点,也不会从mockUser实例中找到线索.
如何获取mockUser mock实例调用的类的详细信息?
提前致谢.
创建一个Mock<IUser>实际创建的新实现IUser.因此,它无法帮助您测试任何实际的实现.
使用这样的Mock工作:
假设我有这个类和接口.该类验证邮政编码是否对某个国家/地区有效.它取决于为给定国家/地区提供正则表达式模式的另一个接口.
public class PostalCodeValidator
{
private readonly IPostalCodeRegexProvider _regexProvider;
public PostalCodeValidator(IPostalCodeRegexProvider regexProvider)
{
_regexProvider = regexProvider;
}
public bool ValidatePostalCode(string postalCode, string countryCode)
{
var regex = _regexProvider.GetPostalCodeRegex(countryCode);
if (string.IsNullOrEmpty(regex)) return true;
return Regex.IsMatch(postalCode, regex);
}
}
public interface IPostalCodeRegexProvider
{
string GetPostalCodeRegex(string countryCode);
}
Run Code Online (Sandbox Code Playgroud)
实施IPostalCodeRegexProvider可以是任何事情.它可以调用数据库,它可以是硬编码的.
但是,当我写单元测试PostalCodeValidator,我明确地不想要测试真正落实IPostalCodeRegexProvider.我想让我的IPostalCodeValidator回报完全符合我的要求,这样我才能确保PostalCodeValidator有效.我只是在测试PostalCodeValidator.
如果我想测试ValidatePostalCode返回true时IPostalCodeRegexProvider.GetPostalCode返回null,然后我需要确保它会返回null.这就是Mock进来的地方.
它允许我轻松创建一个IPostalCodeRegexProvider始终返回null的实现,因此我可以测试ValidatePostalCode该null的用途.
[TestMethod]
public void ValidatePostalCode_ReturnsTrueWhenRegexIsNull()
{
var mock = new Mock<IPostalCodeRegexProvider>();
mock.Setup(x => x.GetPostalCodeRegex(It.IsAny<string>())).Returns(default(string));
var subject = new PostalCodeValidator(mock.Object);
Assert.IsTrue(subject.ValidatePostalCode("xyz","abc"));
}
Run Code Online (Sandbox Code Playgroud)
无论测试的主题是-在这种情况下PostalCodeValidator,或者在您的情况AdminUser和NormalUser-这就是你将创造什么样的一个实例.如果这些类依赖于其他接口,那么您可以Mock为每个接口创建一个.
您还可以考虑使用"测试双倍".您只需创建一个实现接口的简单类,而不是使用Moq.例如,我用Moq做的事情也可以这样做:
public class PostalCodeRegexProviderThatReturnsNull : IPostalCodeRegexProvider
{
public string GetPostalCodeRegex(string countryCode)
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
现在单元测试看起来像这样:
public void ValidatePostalCode_ReturnsTrueWhenRegexIsNull()
{
var regexProvider = new PostalCodeRegexProviderThatReturnsNull();
var subject = new PostalCodeValidator(regexProvider);
Assert.IsTrue(subject.ValidatePostalCode("xyz","abc"));
}
Run Code Online (Sandbox Code Playgroud)
这通常比使用a更容易理解Mock.有时,模拟的设置会变得复杂,难以阅读和调试,但是简单的类可以完成这项工作,甚至更好.
| 归档时间: |
|
| 查看次数: |
368 次 |
| 最近记录: |