方法设置中的Moq匹配和验证阵列/ IEnumerable参数

时间:2009-08-16 20:48:32

标签: unit-testing mocking moq

在设置模拟对象上方法调用的期望时,我在验证Ienumerable / Array类型参数时遇到问题。我认为因为它匹配不同的引用它不认为它匹配。我只是希望它匹配数组的内容,有时我甚至不关心顺序。

mockDataWriter.Setup(m => m.UpdateFiles(new string[]{"file2.txt","file1.txt"} ) );

理想情况下,我想要的东西类似于以下内容,我可能会编写一个扩展方法来执行此操作。

It.Contains(new string[]{"file2.txt","file1.txt"})

It.ContainsInOrder(new string[]{"file2.txt","file1.txt"})

我现在可以匹配这些内置的唯一方法是使用谓词功能,但似乎这个问题很常见,应该内置它。

是否有内置方法来匹配这些类型,或者我可以使用的扩展库。如果不是,我只会写一个扩展方法或其他东西。

谢谢

4 个答案:

答案 0 :(得分:8)

必须实现一些自定义匹配器,在版本3中没有找到任何其他内置方法来实现此目的。使用http://code.google.com/p/moq/wiki/QuickStart作为资源。

public T[] MatchCollection<T>(T[] expectation)
{
  return Match.Create<T[]>(inputCollection => (expectation.All((i) => inputCollection.Contains(i))));
}

public IEnumerable<T> MatchCollection<T>(IEnumerable<T> expectation)
{
  return Match.Create<IEnumerable<T>>(inputCollection => (expectation.All((i) => inputCollection.Contains(i))));
}


public void MyTest()
{

...

mockDataWriter.Setup(m => m.UpdateFiles(MatchCollection(new string[]{"file2.txt","file1.txt"}) ) );

...


}

答案 1 :(得分:4)

Oleg以前的回答并不处理inputCollection包含不在expectation中的元素的情况。

例如:

MatchCollection(new [] { 1, 2, 3, 4 })

将匹配inputCollection { 1, 2, 3, 4, 5 },但显然不应该

这是完整的匹配器:

public static IEnumerable<T> CollectionMatcher<T>(IEnumerable<T> expectation)
{
    return Match.Create((IEnumerable<T> inputCollection) =>
                        !expectation.Except(inputCollection).Any() &&
                        !inputCollection.Except(expectation).Any());
}

答案 2 :(得分:3)

对于数组和IEnumerable,您不需要两个单独的方法:

private static IEnumerable<T> MatchCollection<T>(IEnumerable<T> expectation)
{
    return Match.Create<IEnumerable<T>>(inputCollection => expectation.All(inputCollection.Contains));
}

答案 3 :(得分:0)

我的精简版本:

// ReSharper disable once CheckNamespace
namespace Moq
{
    using System.Collections.Generic;
    using System.Linq;

    public static class MatchCollection<T>
    {
        public static TEnum SequenceEquals<TEnum>(TEnum expectation)
            where TEnum : IEnumerable<T>
        {
            return Match.Create<TEnum>(inputCollection => expectation.SequenceEqual(inputCollection));
        }

        public static TEnum SetEquals<TEnum>(TEnum expectation)
            where TEnum : IEnumerable<T>
        {
            var set = new HashSet<T>(expectation);
            return Match.Create<TEnum>(inputCollection => set.SetEquals(inputCollection));
        }

        public static TEnum Contains<TEnum>(TEnum expectation)
            where TEnum : IEnumerable<T>
        {
            var set = new HashSet<T>(expectation);
            return Match.Create<TEnum>(inputCollection => set.IsSubsetOf(inputCollection));
        }

        public static TEnum IsContainedIn<TEnum>(TEnum expectation)
            where TEnum : IEnumerable<T>
        {
            var set = new HashSet<T>(expectation);
            return Match.Create<TEnum>(inputCollection => set.IsSubsetOf(inputCollection));
        }
    }