在设置模拟对象上方法调用的期望时,我在验证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"})
我现在可以匹配这些内置的唯一方法是使用谓词功能,但似乎这个问题很常见,应该内置它。
是否有内置方法来匹配这些类型,或者我可以使用的扩展库。如果不是,我只会写一个扩展方法或其他东西。
谢谢
答案 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));
}
}