【发布时间】:2013-03-22 17:20:17
【问题描述】:
我很难提取任何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 表示空列表。我不知道为什么我的起订量验证需要内联参数匹配器。
我刚刚发现以下工作:
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 { 课堂节目 { 静态无效主要(字符串 [] 参数) { 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; }
}
}
【问题讨论】:
-
“这失败了”的描述太模糊了。 如何失败了?
-
@JonSkeet:你完全正确。我已经添加了我能想到的所有内容。
-
你能在一个简短但完整的程序中重现这个吗?这将使测试更容易。我怀疑这与类型推断有关,但很难确定。 (Moq 文档链接在项目页面上不起作用也无济于事!)
-
@JustinPihony:感谢您提出的建议。这似乎正是我所遇到的。