Reputation:
I'm still trying to follow the path to TDD.
Let's say I have a SunSystemBroker triggered when a file is uploaded to a Shared Folder. This broker is designed to open this file, extract records from it, try to find associated payments in another systems and finally to call a workflow!
If I want to follow TDD to develop the IBroker.Process() method how shall i do?
Note: Broker are independent assemblies inheriting from IBroker and loaded by a console app (like plugins).
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
}
}
Each method are tested individually.
Thank you Seb
Upvotes: 2
Views: 135
Reputation: 18649
Given that you say each method:
_xlFactory.Create(file);
_hrdbFactory.Create();
// Compare Records
_k2Factory.Create();
is tested individually, there is very little logic to test within Process(file)
.
If you use something like Moq, you can check that the calls occur:
// 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);
For brevity, I've done this as a single test, but breaking into 3 tests with a single "assert" (the verify
calls) is more realistic. For TDD you would write each test, before wiring up that method within Process(file)
.
You may also want to look at having a larger, integration level tests, where you pass in concrete versions of IExcelDatasourceFactory
, IK2DatasourceFactory
, IDbDatasourceFactory
and exercise the system in more depth.
In the book Growing Object-Oriented Software Guided by Tests, this would be defined as an Acceptance Test which would be written before work began, and failing whilst the feature is added in smaller TDD loops of functionality, which work toward the overall feature.
Upvotes: 1
Reputation: 169
you have two different issues :
1) a method is designed to perform many task Make your code SOLID, and apply the single responsibility principle. Split with single responsibility methods : ie responsible for only one task.
2) you want to test a procedure that works by side effect (change environment), not a pure function. So, I would advice you to split your code in pure functions calls (ie : no side effects).
Read also https://msdn.microsoft.com/en-us/library/aa730844%28v=vs.80%29.aspx
Upvotes: 1