unit-testing - Moq - 如何验证方法调用哪个参数已被清除(列表)

标签 unit-testing moq

我有以下代码,我需要帮助为其编写单元测试。我正在使用 Moq 库。

这是交易。我有一个依赖于存储库(接口(interface))的业务类,因此我可以使用它来将我的实体保存到数据库中。我的实体基本上是一个字符串列表。 MyBusinessClass 中的 AddAndSave 方法获取作为参数接收的值,将其放入列表中并调用 IRepository 中的 Save 方法。然后,我清除我的实体列表。下面的代码展示了这个例子(我已经使它变得简单,所以我可以在这里解释它)。

还有单元测试。

using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace TestesGerais
{
    public class MyEntity
    {
        public MyEntity()
        {
            MyList = new List<string>();
        }
        public List<string> MyList { get; set; }
    }

    public interface IRepository
    {
        void Save(MyEntity entity);
    }

    public class MyBusinessClass
    {
        public IRepository Repository { get; set; }
        private MyEntity _entity = new MyEntity();
        public void AddAndSave(string info)
        {
            _entity.MyList.Add(info);
            Repository.Save(_entity);
            _entity.MyList.Clear();  // for some reason I need to clear it
        }
    }

    [TestClass]
    public class UnitTest10
    {
        [TestMethod]
        public void TestMethod1()
        {
            var mock = new Mock<IRepository>();
            MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
            b.AddAndSave("xpto");
            mock.Verify(m => m.Save(It.Is<MyEntity>(x => x.MyList[0] == "xpto")), Times.Exactly(1));
        }
    }
}

我的单元测试检查 IRepository 的 Save 方法是否被调用,其参数(一个实体)在列表中具有一个元素,并且该元素中具有值“xpto”。

当我运行此测试时,它会变成红色,并显示错误消息“测试方法 TestesGerais.UnitTest10.TestMethod1 引发异常: System.ArgumentOutOfRangeException:索引超出范围。必须为非负数且小于集合的大小。 参数名称:索引”。

好的,这是列表被清理导致的。如果我评论“_entity.MyList.Clear();”行,一切都会顺利。

我的问题是:如何在不注释业务类中的“Clear”行的情况下测试这一点,并确保调用我的存储库的方法来传递特定值(具有一个值为“xpto”的元素的实体)?

谢谢

最佳答案

我已经使用 Moq 的回调功能更改了我的单元测试。这样,我可以设置模拟,以便在调用 AddAndSave 时,它​​接收到的参数被保存到我的单元测试中的变量中,并且我可以稍后断言它。

    [TestMethod]
    public void TestMethod1()
    {
        var mock = new Mock<IRepository>();
        string result = string.Empty;
        mock.Setup(m => m.Save(It.IsAny<MyEntity>())).Callback((MyEntity e) => { result = e.MyList[0]; });
        MyBusinessClass b = new MyBusinessClass() { Repository = mock.Object };
        b.AddAndSave("xpto");
        Assert.AreEqual(result, "xpto");
    }

关于unit-testing - Moq - 如何验证方法调用哪个参数已被清除(列表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9267556/

相关文章:

c# - Visual Studio 无法发现测试 (xunit)

algorithm - 单元测试近似算法

ruby-on-rails - 为自定义验证器创建测试

unit-testing - 使用 Moq 和 EF 4.1 模拟 UnitOfWork

c# - Moq - 设置强类型类的返回值

c# - 我应该断言验证方法已执行吗?

node.js - 使用 Mocha 进行测试之前清除集合

android - 单元测试 LiveData android.os.Looper 未模拟

c# - 无法验证对具有多个接口(interface)的模拟对象上的方法的调用

c# - Moq:如何获取传递给模拟服务方法的参数