I have created a fluent builder style pattern for helping with data loading my tests. The order of certain methods is important and was wondering what the preferred method to managing the correct sequence is.
I have the following at the moment:
using NUnit.Framework;
[TestFixture]
public class DataBuilderTests
{
[Test]
public void Can_NAME()
{
new DataLoader()
.Start() // must be called first
.Setup() // then called next
.LoadEmployees() // optional order not NB
.LoadProducts() // optional order not NB
.StartCleanup() // begin cleanup
.CleanupEmployees() // optional order not NB
.CleanupProducts() // optional order not NB
.End();
}
}
public class DataLoader
{
public DataBuilderSetup Start()
{
return new DataBuilderSetup(this);
}
}
public class DataBuilderSetup
{
private readonly DataLoader _dataLoader;
public DataBuilderSetup(DataLoader dataLoader)
{
_dataLoader = dataLoader;
}
public DataBuilderOptions Setup()
{
// do setup
return new DataBuilderOptions(_dataLoader);
}
}
public class DataBuilderOptions
{
private readonly DataLoader _dataLoader;
public DataBuilderOptions(DataLoader dataLoader)
{
_dataLoader = dataLoader;
}
public DataBuilderOptions LoadEmployees()
{
// load
return this;
}
public DataBuilderOptions LoadProducts()
{
// load
return this;
}
public DataBuilderCleanupOptions StartCleanup()
{
return new DataBuilderCleanupOptions(_dataLoader);
}
}
public class DataBuilderCleanupOptions
{
private readonly DataLoader _dataLoader;
public DataBuilderCleanupOptions(DataLoader dataLoader)
{
_dataLoader = dataLoader;
}
public DataBuilderCleanupOptions CleanupEmployees()
{
// cleanup
return this;
}
public DataBuilderCleanupOptions CleanupProducts()
{
// cleanup
return this;
}
public DataLoader End()
{
return _dataLoader;
}
}
In Java (C# and its multiple inheritance shouldn't make it any different) you could do it that way:
declare set of interfaces, that contain one method only:
Interface DoFirstThing { // could be renamed to "BuilderOnStart" or "BuilderStartingState"
DoSecondThing doFirst();
}
Interface DoSecondThing {
DoLastThing doSecond();
}
Interface DoLastThing {
BuilderReady doLast();
}
Interface BuilderReady {
Result build();
}
class BuilderWithForcedSequence implements DoFirstThing, DoSecondThing, DoLastThing, BuilderReady {
// implement all
}
and finally you would need some factory or factory method to set the initial state for that builder:
public DoFirstThing createNewBuilderWithForcedSequence(requiredParameters){
return new BuilderWithForcedSequence(requiredParameters);
}
This would produce Builder, with forced ordering of building methods (they should be renamed from doThat
to something meaningful), that can call only doFirst()
, after that doSecond()
... and so on, till final state, when obiect would be build, using build()
method.
Result result = builder.doFirst().doSecond().doLast().build();
EDIT:
Oops, that's pretty exact your approach :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With