我正在尝试使用FakeItEasy(版本4.9.1)为某些旧代码创建单元测试。我已经创建了两个单元测试,其中一个可以按预期工作,而另一个非常相似,尽管经过反复试验,仍然无法正常工作。
以下是该方法的摘录,似乎无法测试:
public class PosMessageProcessor : IPosMessageProcessor
{
public void Execute()
{
PurchaseOrderRepository repo = new PurchaseOrderRepository();
...
try
{
m_PurchaseOrder = GetOrderForProcessing(repo);
...
这是我的测试:
[TestMethod]
[TestCategory("POS")]
public void ExecuteTest()
{
// Arrange
PurchaseOrder purchaseOrder = GetPurchaseOrder();
IPosMessageProcessor fakePosMessageProcessor = A.Fake<IPosMessageProcessor>();
A.CallTo(() => fakePosMessageProcessor.GetOrderForProcessing(A<IPurchaseOrderRepository>.Ignored)).Returns(purchaseOrder);
// Act
_posMessageProcessor.Execute();
// Assert
A.CallTo(() => fakePosMessageProcessor.GetOrderForProcessing(A<IPurchaseOrderRepository>.Ignored)).MustHaveHappened();
}
_posMessageProcessor
变量是PosMessageProcessor
类的实例。我想捕获对GetOrderForProcessing()
方法的调用(在Execute()
方法内),并使其返回我的硬编码purchaseOrder
对象。但是我得到了另一个返回值(null
)。为什么?
有效的单元测试将测试GetOrderForProcessing()
方法:
[TestMethod]
[TestCategory("POS")]
public void GetOrderForProcessingTest()
{
// Arrange
PurchaseOrder purchaseOrder = GetPurchaseOrder();
IPurchaseOrderRepository fakePurchaseOrderRepository = A.Fake<IPurchaseOrderRepository>();
A.CallTo(() => fakePurchaseOrderRepository.GetPurchaseOrderByOrderTrackingNumber(A<string>.Ignored)).Returns(purchaseOrder);
// Act
PurchaseOrder result = _posMessageProcessor.GetOrderForProcessing(fakePurchaseOrderRepository);
// Assert
A.CallTo(() => fakePurchaseOrderRepository.GetPurchaseOrderByOrderTrackingNumber(A<string>.Ignored)).MustHaveHappened();
Assert.IsNotNull(result);
}
在这种情况下,对GetPurchaseOrderByOrderTrackingNumber()
的调用将按预期返回我的硬编码对象。这两个测试实际上是相同的,除了GetOrderForProcessing()
方法接受一个参数而Execute()
不接受参数。
答案 0 :(得分:1)
ExecuteTest
失败,因为您配置了伪造的IPosMessageProcessor
,然后在真实的Execute
,PosMessageProcessor
上调用_posMessageProcessor
。 _posMessageProcessor
是实际的PosMessageProcessor
,将执行其常规代码路径,并调用实际的Execute
,而实际的GetOrderForProcessing
将调用实际的fakePosMessageProcessor
。
(请注意,您实际上可以从测试中删除GetOrderForProcessing
变量及其所有引用,其行为将是相同的。)
我不推荐这种测试,但是为了伪造Execute
并仍然测试实际的public void NewExecuteTest()
{
// Arrange
PurchaseOrder purchaseOrder = GetPurchaseOrder();
// Get a fake PosMessageProcessor that falls back to original behaviour for all calls.
IPosMessageProcessor fakePosMessageProcessor = A.Fake<PosMessageProcessor>(options => options.CallsBaseMethods());
// Now fake out the GetOrderForProcessing call so we can test Execute.
A.CallTo(() => fakePosMessageProcessor.GetOrderForProcessing(A<IPurchaseOrderRepository>.Ignored)).Returns(purchaseOrder);
// Act
fakePosMessageProcessor.Execute();
// Assert
A.CallTo(() => fakePosMessageProcessor.GetOrderForProcessing(A<IPurchaseOrderRepository>.Ignored)).MustHaveHappened();
}
代码,您必须编写类似的测试
nineteen=year[year>=60]+1900
twenty=year[year<60]+2000
year=c(nineteen,twenty)