我很难提取任何It.Is<T>
参数匹配器变量。每当我这样做时,测试都会失败。
这有效:
calculatorMock
.Setup(x => x.Produce(It.Is<IEnumerable<Report>>(xx => reports.IsEqualTo(xx))))
.Returns(calculatorInputs);
但是,这失败了:
var argumentMatcher = It.Is<IEnumerable<Report>>(xx => reports.IsEqualTo(xx));
calculatorMock
.Setup(x => x.Produce(argumentMatcher))
.Returns(calculatorInputs);
IsEqualTo
是一个返回 bool 的静态方法。
问题是 Moq 说Produce()
当我期望它被一个包含 3 个项目的列表调用时,它是用一个空列表调用的。在本例中,xx
表示空列表。我不确定为什么我的 Moq 验证需要内联参数匹配器。
我刚刚发现以下工作:
Expression<Func<IEnumerable<Report>, bool>> expression = x => reports.IsEqualTo(x);
calculatorMock
.Setup(x => x.Produce(It.Is(expression)))
.Returns(calculatorInputs);
是否有特定原因It.Is<T>
无法像我上面尝试的那样提取?
这是问题的工作副本:
使用系统;使用 System.Linq.Expressions;使用最小起订量;使用 Xunit;
命名空间 MoqArgumentMatcher { 类程序 { 静态 void Main(string[] args) { var testRunner = new TestRunner();
testRunner.Passes();
testRunner.Fails();
Console.ReadKey();
}
}
public class TestRunner
{
[Fact]
public void Passes()
{
// Arrange
var calculatorMock = new Mock<ICalculator>();
var consumer = new CalculatorConsumer(calculatorMock.Object);
var report = new Report {Id = 1};
// Act
consumer.Consume(report);
// Assert
calculatorMock.Verify(x => x.Produce(
It.Is<Report>(xx => xx.Id == 1)), Times.Once());
}
[Fact]
public void Passes2()
{
// Arrange
var calculatorMock = new Mock<ICalculator>();
var consumer = new CalculatorConsumer(calculatorMock.Object);
var report = new Report { Id = 1 };
// Act
consumer.Consume(report);
// Assert
Expression<Func<Report, bool>> expression = x => x.Id == 1;
calculatorMock.Verify(x => x.Produce(It.Is(expression)), Times.Once());
}
[Fact]
public void Fails()
{
// Arrange
var calculatorMock = new Mock<ICalculator>();
var consumer = new CalculatorConsumer(calculatorMock.Object);
var report = new Report {Id = 1};
// Act
consumer.Consume(report);
// Assert
var argumentMatcher = It.Is<Report>(xx => xx.Id == 1);
calculatorMock.Verify(x => x.Produce(argumentMatcher), Times.Once());
}
}
public class CalculatorConsumer
{
private readonly ICalculator _calculator;
public CalculatorConsumer(ICalculator calculator)
{
_calculator = calculator;
}
public void Consume(Report report)
{
_calculator.Produce(report);
}
}
public interface ICalculator
{
void Produce(Report report);
}
public class Report
{
public int Id { get; set; }
}
}