当您的方法旨在执行许多任务时如何使用 TDD
How to use TDD when your method is designed to perform many tasks
我仍在努力遵循 TDD 之路。
假设我在文件上传到共享文件夹时触发了 SunSystemBroker。此代理旨在打开此文件,从中提取记录,尝试在另一个系统中查找关联的付款,最后调用工作流!
If I want to follow TDD to develop the IBroker.Process() method how shall i do?
注意:Broker 是继承自 IBroker 并由控制台应用程序(如插件)加载的独立程序集。
This console is in charge of triggering each broker!
public interface IFileTriggeredBroker : IBroker
{
FileSystemTrigger Trigger { get; }
void Process(string file);
}
public class SunSystemPaymentBroker : IFileTriggeredBroker
{
private readonly IDbDatasourceFactory _hrdbFactory;
private readonly IExcelDatasourceFactory _xlFactory;
private readonly IK2DatasourceFactory _k2Factory;
private ILog _log;
public void Process(string file)
{
(...)
// _xlFactory.Create(file) > Extract
// _hrdbFactory.Create() > Find
// Compare Records
// _k2Factory.Create > Start
}
}
每种方法都经过单独测试。
谢谢
塞布
您有两个不同的问题:
1) 一种方法被设计来执行许多任务
使您的代码可靠,并应用单一责任原则。
拆分单一责任方法:即只负责一个任务。
2) 你想测试一个通过副作用(改变环境)起作用的过程,而不是一个纯函数。
因此,我建议您将代码拆分为纯函数调用(即:无副作用)。
另读https://msdn.microsoft.com/en-us/library/aa730844%28v=vs.80%29.aspx
鉴于你说的每个方法:
_xlFactory.Create(file);
_hrdbFactory.Create();
// Compare Records
_k2Factory.Create();
是单独测试的,在Process(file)
.
内测试的逻辑很少
如果您使用 Moq 之类的东西,您可以检查调用是否发生:
// Arrange
const string File = "file.xlsx";
var xlFactory = new Mock<IExcelDatasourceFactory>();
var hrbdFactory = new Mock<IDbDatasourceFactory>();
var k2Factory = new Mock<IK2DatasourceFactory>();
// Act
var sut = new SunSystemPaymentBroker(xlFactory.Object, hrdbFactory.Object, k2Factory.Object); // I'm assuming you're using constructor injection
sut.ProcessFile(File);
// Assert
xlFactory.Verify(m => m.Create(File), Times.Once);
hrbdFactory.Verify(m => m.Create(), Times.Once);
k2Factory.Verify(m => m.Create(), Times.Once);
为简洁起见,我将此作为一个测试来完成,但是用一个 "assert"(verify
调用)分成 3 个测试更为现实。对于 TDD,您将编写每个测试,然后在 Process(file)
.
中连接该方法
您可能还想看看有一个更大的集成级别测试,您可以在其中通过 IExcelDatasourceFactory
、IK2DatasourceFactory
、IDbDatasourceFactory
的具体版本,并在更多方面练习系统深度。
在书 Growing Object-Oriented Software Guided by Tests 中,这将被定义为 验收测试 将在工作开始之前编写,并且在较小的 TDD 中添加该功能时失败功能循环,对整体功能起作用。
我仍在努力遵循 TDD 之路。
假设我在文件上传到共享文件夹时触发了 SunSystemBroker。此代理旨在打开此文件,从中提取记录,尝试在另一个系统中查找关联的付款,最后调用工作流!
If I want to follow TDD to develop the IBroker.Process() method how shall i do?
注意:Broker 是继承自 IBroker 并由控制台应用程序(如插件)加载的独立程序集。
This console is in charge of triggering each broker!
public interface IFileTriggeredBroker : IBroker
{
FileSystemTrigger Trigger { get; }
void Process(string file);
}
public class SunSystemPaymentBroker : IFileTriggeredBroker
{
private readonly IDbDatasourceFactory _hrdbFactory;
private readonly IExcelDatasourceFactory _xlFactory;
private readonly IK2DatasourceFactory _k2Factory;
private ILog _log;
public void Process(string file)
{
(...)
// _xlFactory.Create(file) > Extract
// _hrdbFactory.Create() > Find
// Compare Records
// _k2Factory.Create > Start
}
}
每种方法都经过单独测试。
谢谢 塞布
您有两个不同的问题:
1) 一种方法被设计来执行许多任务 使您的代码可靠,并应用单一责任原则。 拆分单一责任方法:即只负责一个任务。
2) 你想测试一个通过副作用(改变环境)起作用的过程,而不是一个纯函数。 因此,我建议您将代码拆分为纯函数调用(即:无副作用)。
另读https://msdn.microsoft.com/en-us/library/aa730844%28v=vs.80%29.aspx
鉴于你说的每个方法:
_xlFactory.Create(file);
_hrdbFactory.Create();
// Compare Records
_k2Factory.Create();
是单独测试的,在Process(file)
.
如果您使用 Moq 之类的东西,您可以检查调用是否发生:
// Arrange
const string File = "file.xlsx";
var xlFactory = new Mock<IExcelDatasourceFactory>();
var hrbdFactory = new Mock<IDbDatasourceFactory>();
var k2Factory = new Mock<IK2DatasourceFactory>();
// Act
var sut = new SunSystemPaymentBroker(xlFactory.Object, hrdbFactory.Object, k2Factory.Object); // I'm assuming you're using constructor injection
sut.ProcessFile(File);
// Assert
xlFactory.Verify(m => m.Create(File), Times.Once);
hrbdFactory.Verify(m => m.Create(), Times.Once);
k2Factory.Verify(m => m.Create(), Times.Once);
为简洁起见,我将此作为一个测试来完成,但是用一个 "assert"(verify
调用)分成 3 个测试更为现实。对于 TDD,您将编写每个测试,然后在 Process(file)
.
您可能还想看看有一个更大的集成级别测试,您可以在其中通过 IExcelDatasourceFactory
、IK2DatasourceFactory
、IDbDatasourceFactory
的具体版本,并在更多方面练习系统深度。
在书 Growing Object-Oriented Software Guided by Tests 中,这将被定义为 验收测试 将在工作开始之前编写,并且在较小的 TDD 中添加该功能时失败功能循环,对整体功能起作用。