如何最小化 IEnumerable<T> 以通过 Any() 条件检查
How to moq a IEnumerable<T> to pass Any() condition check
我在将 Moq
框架与 IEnumerable
一起使用时遇到了一些问题。我对模拟一个对象没有问题,但是我对模拟一个对象的 IEnumerable
、ICollection
等等有些事情不了解。
例如:
[TestMethod]
public void UnitTest()
{
var mockedExample = new Mock<IEnumerable<Class>>();
var feedback = repository.SomeMethod(mockedExample.Object);
}
public void SomeMethod(IEnumerable<Class> input)
{
if (input != null && input.Any())
{
//Stuff to do
}
}
我的问题是检查输入时。我通过了 input != null
条件,但在 input.Any()
条件下出现错误。
如何设置模拟的 IEnumerable 以通过这两个条件?
提前致谢。
正如人们所说,我认为您在这里不需要模拟。我认为评论中提供了正确的选项。
但要回答您的问题:您应该指定 Any 方法的行为(在模拟中使用“setup”方法):
mockedExample.Setup(m => m.Any()).Returns(true);
但如果您尝试这样做,您将遇到此异常:
System.NotSupportedException: 'Unsupported expression: m =>
m.Any() Extension methods (here: Enumerable.Any) may not be
used in setup / verification expressions.'
那是因为,“Any”不是 IEnumerable 接口的一部分(即使用法往往让您相信它是)。 “Any”是 IEnumerable 的扩展方法(所以基本上是一个简单的静态方法)。
public static bool Any<TSource> (this System.Collections.Generic.IEnumerable<TSource> source)
这基本上意味着您不能直接使用 Moq 模拟“Any”方法的行为。
但是,如果您检查“Any”方法中的内容:
public static bool Any<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw new Exception();
}
using (IEnumerator<TSource> e = source.GetEnumerator())
{
return e.MoveNext();
}
}
当您的模拟对象的 GetEnumerator 被调用时,默认值被返回(因为您没有为它设置任何行为)它是“null”,因此“e.MoveNext()”调用失败。因此,您可以定义“GetEnumerator”行为并使其工作,但我真的认为评论中提供的解决方案更简单,并且会使代码更具可读性。
我在将 Moq
框架与 IEnumerable
一起使用时遇到了一些问题。我对模拟一个对象没有问题,但是我对模拟一个对象的 IEnumerable
、ICollection
等等有些事情不了解。
例如:
[TestMethod]
public void UnitTest()
{
var mockedExample = new Mock<IEnumerable<Class>>();
var feedback = repository.SomeMethod(mockedExample.Object);
}
public void SomeMethod(IEnumerable<Class> input)
{
if (input != null && input.Any())
{
//Stuff to do
}
}
我的问题是检查输入时。我通过了 input != null
条件,但在 input.Any()
条件下出现错误。
如何设置模拟的 IEnumerable 以通过这两个条件?
提前致谢。
正如人们所说,我认为您在这里不需要模拟。我认为评论中提供了正确的选项。
但要回答您的问题:您应该指定 Any 方法的行为(在模拟中使用“setup”方法):
mockedExample.Setup(m => m.Any()).Returns(true);
但如果您尝试这样做,您将遇到此异常:
System.NotSupportedException: 'Unsupported expression: m => m.Any() Extension methods (here: Enumerable.Any) may not be used in setup / verification expressions.'
那是因为,“Any”不是 IEnumerable 接口的一部分(即使用法往往让您相信它是)。 “Any”是 IEnumerable 的扩展方法(所以基本上是一个简单的静态方法)。
public static bool Any<TSource> (this System.Collections.Generic.IEnumerable<TSource> source)
这基本上意味着您不能直接使用 Moq 模拟“Any”方法的行为。
但是,如果您检查“Any”方法中的内容:
public static bool Any<TSource>(this IEnumerable<TSource> source)
{
if (source == null)
{
throw new Exception();
}
using (IEnumerator<TSource> e = source.GetEnumerator())
{
return e.MoveNext();
}
}
当您的模拟对象的 GetEnumerator 被调用时,默认值被返回(因为您没有为它设置任何行为)它是“null”,因此“e.MoveNext()”调用失败。因此,您可以定义“GetEnumerator”行为并使其工作,但我真的认为评论中提供的解决方案更简单,并且会使代码更具可读性。