FakeItEasy:未使用简单假货
FakeItEasy: Simple Fake not being used
我正在尝试使用 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
class 的实例。我想捕获对 GetOrderForProcessing()
方法的调用(在 Execute()
方法中)并使其成为 return 我的硬编码 purchaseOrder
对象。但是我得到了另一个 return 值 (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()
return 是我预期的硬编码对象。这两个测试实际上是相同的,除了 GetOrderForProcessing()
方法需要一个参数而 Execute()
没有。
ExecuteTest
失败,因为您配置了假的 IPosMessageProcessor
,然后在真实的 PosMessageProcessor
、_posMessageProcessor
上调用了 Execute
。 _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();
}
我正在尝试使用 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
class 的实例。我想捕获对 GetOrderForProcessing()
方法的调用(在 Execute()
方法中)并使其成为 return 我的硬编码 purchaseOrder
对象。但是我得到了另一个 return 值 (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()
return 是我预期的硬编码对象。这两个测试实际上是相同的,除了 GetOrderForProcessing()
方法需要一个参数而 Execute()
没有。
ExecuteTest
失败,因为您配置了假的 IPosMessageProcessor
,然后在真实的 PosMessageProcessor
、_posMessageProcessor
上调用了 Execute
。 _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();
}