Использование Moq с Linq Any()
У меня есть настройки, аналогичные приведенным ниже:
[TestMethod]
public void NoIntegers()
{
Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
Mock<IEnumerable<int>> mockIntegers = new Mock<IEnumerable<int>>(MockBehavior.Strict);
mockBar
.SetupGet(x => x.Integers)
.Returns(mockIntegers.Object);
mockIntegers
.Setup(x => x.Any())
.Returns(false);
Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
}
public interface IBar
{
IEnumerable<int> Integers { get; }
}
public class Foo
{
private IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
public bool AreThereIntegers()
{
return _bar.Integers.Any();
}
}
}
Когда он работает, он не может инициализировать макет
Test method NoIntegers threw exception: System.NotSupportedException: Expression references a method that does not belong to the mocked object: x => x.Any<Int32>()
У меня есть попытки добавления It.IsAny()
в нескольких формах:
mockIntegers
.Setup(x => x.Any(It.IsAny<IEnumerable<int>>(), It.IsAny<Func<int, bool>>()))
.Returns(false);
// No method with this signiture
mockIntegers
.Setup(x => x.Any(It.IsAny<Func<int, bool>>()))
.Returns(false);
// Throws: Test method NoIntegers threw exception:
// System.NotSupportedException:
// Expression references a method that does not belong to the mocked object:
// x => x.Any<Int32>(It.IsAny<Func`2>())
Что мне нужно издеваться, чтобы это запустилось?
3 ответа
Вы должны издеваться Integers
только собственность Не надо издеваться Any()
(в любом случае вы не можете сделать это, потому что это метод расширения), потому что он является частью SUT. Вот как вы должны сделать это для двух случаев:
[TestMethod]
public void NoIntegers()
{
Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
mockBar.SetupGet(x => x.Integers)
.Returns(new List<int>());
Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
}
[TestMethod]
public void HasIntegers()
{
Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
mockBar.SetupGet(x => x.Integers)
.Returns(new List<int>{ 3, 5, 6});
Assert.IsTrue(new Foo(mockBar.Object).AreThereIntegers());
}
Исправлена!
Не красиво, но это насмешка, которая нужна:
[TestMethod]
public void NoIntegers()
{
Mock<IBar> mockBar = new Mock<IBar>(MockBehavior.Strict);
Mock<IEnumerable<int>> mockIntegers = new Mock<IEnumerable<int>>(MockBehavior.Strict);
Mock<IEnumerator<int>> mockEnumerator = new Mock<IEnumerator<int>>(MockBehavior.Strict);
mockBar
.SetupGet(x => x.Integers)
.Returns(mockIntegers.Object);
mockIntegers
.Setup(x => x.GetEnumerator())
.Returns(mockEnumerator.Object);
mockEnumerator.Setup(x => x.MoveNext()).Returns(false);
mockEnumerator.Setup(x => x.Dispose());
Assert.IsFalse(new Foo(mockBar.Object).AreThereIntegers());
}
public interface IBar
{
IEnumerable<int> Integers { get; }
}
public class Foo
{
private IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
public bool AreThereIntegers()
{
return _bar.Integers.Any();
}
}
Это не работает, потому что Any()
метод не подвергается непосредственному IEnumerable<T>
интерфейс, но он определяется как метод расширения наEnumerable
,
Я не думаю, что вы можете настроить звонок Any()
на любом макете, потому что это по сути статический метод.
В этом случае я думаю, что предпочтительнее использовать экземпляр IEnumerable<int>
(например, массив int), который может быть установлен как пустой / непустой, в зависимости от того, что вы тестируете.