gpt4 book ai didi

c# - It.IsAny() 用作模拟对象

转载 作者:行者123 更新时间:2023-11-30 14:10:49 25 4
gpt4 key购买 nike

使用最小起订量,通常为接口(interface)类型提供模拟 T通过使用 Mock.Of<T>() .但是或者It.IsAny<T>()返回一个表达式,它似乎也可用作对象来代替 T 类型的对象.我只看过It.IsAny<T>()用于为 Setup() 中的方法调用定义参数. Mock.Of<T>() 之间有什么区别?和 It.IsAny<T>() (显然除了语法)?在任何情况下It.IsAny<T>()应该用于提供模拟 Mock.Of<T>()

这是我要问的一个例子,我将以 Ufuk 的回答为基础。提供给 new UserService() 的模拟可以是 It.IsAny<IUserRepository>()Mock.Of<IUserRepository>() .在这种情况下,我对为这些模拟设置任何特殊设置不感兴趣,只是它们的存在是为了满足编译器的需求。 Assert.IsTrue()语句与提供的 IUserRepository 无关为了这些测试的目的。问题是:是 It.IsAny<IUserRepository>()Mock.Of<IUserRepository>()在这种情况下功能等效吗?

[TestFixture]
public class MoqTests
{
[Test]
public void TestInitializationWithItIsAny()
{
var subject = new UserService( It.IsAny<IUserRepository>() ); // It.IsAny<T>
_userService.RegisterUser("abc");
Assert.IsTrue( _userService.IsInitialized() );
}

[Test]
public void TestInitializationWithMockOf()
{
var subject = new UserService( Mock.Of<IUserRepository>() ); // Mock.Of<T>
_userService.RegisterUser("abc");
Assert.IsTrue( _userService.IsInitialized() );
}
}

public class UserService
{
private readonly IUserRepository _userRepository;
private bool _isInitialized = false;

public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}

public bool RegisterUser(string userName)
{
_isInitialized = true;
User user = new User { UserName = userName, CreatedOn = DateTime.Now };
return _userRepository.RegisterUser(user);
}

public bool IsInitialized()
{
return _isInitialized;
}
}

public interface IUserRepository
{
bool RegisterUser(User user);
}

public class User
{
public string UserName { get; set; }
public DateTime CreatedOn { get; set; }
}

最佳答案

It.IsAny<T>用于跳过模拟方法参数中的验证。

serviceMock.Setup(mock => mock.GetUser(It.IsAny<int>())).Returns(someResult);

您必须在模拟回调中传递一个整数作为参数才能使测试通过。您可能不知道什么值将被发送到模拟组件(对于引用类型通常为真)或者您可能根本不关心。 It.IsAny<T>()使您可以编写没有过度规范的测试。

It.IsAny<T>()返回 T 的实例, 不是 Mock<T>所以这不是模拟。

看看这些测试用例:

[TestFixture]
public class MoqTests
{
private Mock<IUserRepository> _repository;
private UserService _userService;

[SetUp]
public void Setup()
{
_repository = new Mock<IUserRepository>(MockBehavior.Strict);
_userService = new UserService(_repository.Object);
}

[Test]
public void RegisterUserWithItIsAny()
{
_repository.Setup(item => item.RegisterUser(It.IsAny<User>())).Returns(true);

bool result = _userService.RegisterUser("abc");

Assert.True(result);
}

[Test]
public void RegisterUserWithMockOf()
{
_repository.Setup(item => item.RegisterUser(Mock.Of<User>())).Returns(true);

bool result = _userService.RegisterUser("abc");

Assert.True(result);
}

[TearDown]
public void TearDown()
{
_repository.VerifyAll();
}
}

public class UserService
{
private readonly IUserRepository _userRepository;

public UserService(IUserRepository userRepository)
{
_userRepository = userRepository;
}

public bool RegisterUser(string userName)
{
User user = new User { UserName = userName, CreatedOn = DateTime.Now };
return _userRepository.RegisterUser(user);
}
}

public interface IUserRepository
{
bool RegisterUser(User user);
}

public class User
{
public string UserName { get; set; }
public DateTime CreatedOn { get; set; }
}

第二次测试失败,因为 Moq 无法将模拟实例识别为参数值。 Mock.Of<T>()当您想使用谓词参数中包含的单个设置快速创建模拟时,这似乎很有用。

更新:

我按照您的示例重写了测试。

[SetUp]
public void Setup()
{
_userService = new UserService(It.IsAny<IUserRepository>());
}

[Test]
public void RegisterUserWithItIsAny()
{
bool result = _userService.RegisterUser("abc");

Assert.True(result);
}

[Test]
public void RegisterUserWithMockOf()
{
bool result = _userService.RegisterUser("abc");

Assert.True(result);
}

两个测试都失败了,因为 It.IsAny<T>()返回空值。如果你用过Mock.Of<T>()它会创建一个具有默认行为的模拟。这意味着它们在这种情况下在功能上也不等同。

关于c# - It.IsAny<T>() 用作模拟对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22373236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com