加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 02:00:37 所属栏目:百科 来源:网络整理
导读:使用moq,通常使用Mock.Of T()为接口类型T提供模拟.但另外,It.IsAny T()返回一个表达式,它似乎也可用作对象来代替类型为T的对象.我只看到It.IsAny T()用于定义方法的参数调用Setup(). Mock.Of T()和It.IsAny T()之间有什么区别(显然除了语法)?在任何情况下都
使用moq,通常使用Mock.Of< T>()为接口类型T提供模拟.但另外,It.IsAny< T>()返回一个表达式,它似乎也可用作对象来代替类型为T的对象.我只看到It.IsAny< T>()用于定义方法的参数调用Setup(). Mock.Of< T>()和It.IsAny< T>()之间有什么区别(显然除了语法)?在任何情况下都应该使用It.IsAny< T>()来提供模拟Mock.Of< T>()?

这是我要问的一个例子,我将以Ufuk的答案为基础.提供给新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);

您必须在mock回调中传递一个整数作为参数才能进行测试编译.您可能不知道将哪些值发送到模拟组件(对于引用类型通常是真的),或者您甚至可能不关心. 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实例识别为参数值.当您想要使用谓词参数中包含的单个设置快速创建模拟时,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>()返回null.如果您使用过Mock.Of< T>(),它将创建一个具有默认行为的模拟.这意味着它们在这种情况下在功能上也不相同.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读