【问题标题】:Verifying an enumerable list in Moq验证 Moq 中的可枚举列表
【发布时间】:2013-01-24 12:20:26
【问题描述】:

我正在尝试为如下所示的方法编写单元测试:

public int Save(IEnumerable<int> addedIds, IEnumerable<int> removedIds)
{
    var existingIds = repository.Get();
    IEnumerable<int> ids = existingIds.Except(removedIds).Union(addedIds));
    return repository.Create(ids);
}

Moq 中的测试如下所示:

repository.Setup(r => r.Get()).Returns(CreateList());
service.Save(addedIds, removedIds);
repository.Verify(r => r.Create(It.Is<IEnumerable<int>>(l => VerifyList(l))));

失败,出现此错误,并且永远不会调用VerifyList()

预计至少会在模拟上调用一次,但从来没有 执行:

r =&gt; r.Create(It.Is&lt;IEnumerable'1&gt;(list =&gt; VerifyList(list)))

执行的调用:

IRepo.Create(System.Linq.Enumerable+&lt;UnionIterator&gt;d__88'1[System.Int32])

由于调用的类型不是IEnumerable&lt;int&gt; 而实际上是System.Linq.Enumerable+&lt;UnionIterator&gt;d__88'1[System.Int32]),因此测试失败。 (逐步测试,一切正常,结果符合预期)

如果我在被测方法中调用ids.ToList(),结果如下:

预期至少对模拟调用一次,但从未执行:

r =&gt; r.Create(It.Is&lt;List'1&gt;(l =&gt; VerifyList(l)))

执行的调用: IRepo.Create(System.Collections.Generic.List'1[System.Int32])

有没有办法解决这个问题?还是我做错了什么?

编辑:原来我的 VerifyList 方法有误,所以它返回 false,但 Moq 没有给我该信息。类型差异是一个红鲱鱼..

【问题讨论】:

    标签: c# unit-testing moq


    【解决方案1】:

    这似乎有效。不过做了一些假设。猜测 VerifyList 方法可能会更好。 =)

    [Test]
        public void Test()
        {
            // SETUP
            Mock<IRepository> repository = new Mock<IRepository>();
            Service service = new Service(repository.Object);
            repository.Setup(r => r.Get()).Returns(CreateList());
    
            IEnumerable<int> addedIds = new[]{1,2};
            IEnumerable<int> removedIds = new[]{3,4};
            service.Save(addedIds, removedIds);
    
            repository.Verify(r => r.Create(It.Is<IEnumerable<int>>(l => VerifyList(l))));
        }
    
        private static bool VerifyList(IEnumerable<int> enumerable)
        {
            return enumerable.Contains(1) && enumerable.Contains(2) && enumerable.Contains(5);
        }
    
        private IEnumerable<int> CreateList()
        {
            return new[] { 3, 4, 5 };
        }
    
        public interface IRepository
        {
            IEnumerable<int> Get();
            int Create(IEnumerable<int> id);
        }
        public class Service
        {
            public Service(IRepository repository)
            {
                this.repository = repository;
            }
    
            private IRepository repository;
    
            public int Save(IEnumerable<int> addedIds, IEnumerable<int> removedIds)
        {
            var existingIds = repository.Get();
                IEnumerable<int> ids = existingIds.Except(removedIds).Union(addedIds);
    
            return repository.Create(ids);
        }
    

    【讨论】:

    • 谢谢,我的 Moq 版本确实通过了该测试。我仍然不明白为什么我的失败..
    • 这很奇怪。你能更新起订量吗?您使用的是哪个版本的起订量?
    • 我的 VerifyList 方法出现错误,结果证明它最终被调用了。谢谢你的帮助..
    【解决方案2】:

    你可以这样做:

    var another = new List<int> { 1 , 2, 3 };
    repository.Verify(r => r.Create(It.Is<IEnumerable<int>>(l => l.SequenceEqual(another)));
    

    【讨论】:

      【解决方案3】:

      一些又快又脏的东西 -

      public interface IBlah
      {
          void Sum(IEnumerable<int> baz);
      }
      
      class Blah : IBlah
      {
          public void Sum(IEnumerable<int> baz)
          {
              return;
          }
      }
      
      public class Baz
      {
          private readonly IBlah blah;
      
          public Baz(IBlah blah)
          {
              this.blah = blah;
          }
      
          public void Sum(IEnumerable<int> baz)
          {
              blah.Sum(baz);
          }
      }
      

      然后像这样测试它 -

      [Test]
      public void foo()
      {
          var mock = new Mock<IBlah>();
          var enumerable = Enumerable.Range(1, 10);
      
          var baz = new Baz(mock.Object);
          baz.Sum(enumerable.Where(x => x%2 == 0));
      
          mock.Verify(p => p.Sum(It.Is<IEnumerable<int>>(z => z.All(x => x%2==0))));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-17
        • 1970-01-01
        • 2010-09-06
        • 2012-07-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-25
        • 2017-12-14
        相关资源
        最近更新 更多