Just a quick update!! After thinking a bit more about the problems mentioned by Aaron in my previous post, and taking a look at Cucumber (in ruby), I decided to give it another go. Since I have to be in the shop within half an hour 20 mins, I can only give you a sample of what the current spec looks like; explanations will come in later posts... I'm also considering a rename, since netspec already seemed to exist as a .NET spec platform...
Since Cucumber was my inspiration, I'm currently thinking about Aubergine/Eggplant. Suggestions are welcome.
I'm not really fond of the implementation yet, but I'll have to think about that a little bit more... As you might notice, there has been a slight shift towards the Cucumber
method of doing things.
Here we go:
class TransferFundsBetweenAccounts : Story
{
AsAn AccountUser;
IWant ToTransferMoneyBetweenAccounts;
SoThat ICanHaveRealUseForMyMoney;
class Transfer1MBetweenTwoAccounts : Scenario<Context>
{
Given AccountAHas1M;
Given AccountBHas1M;
When Transfering1MFromAccountAToAccountB;
Then ShouldHave0MOnAccountA;
Then ShouldHave2MOnAccountB;
}
class TransferTooMuch : Scenario<Context>
{
Given AccountAHas1M;
Given AccountBHas1M;
When Transfering3MFromAccountAToAccountB;
Then ShouldHave1MOnAccountA;
Then ShouldHave1MOnAccountB;
Then ShouldFailWithError;
}
class Context
{
public Account AccountA = new Account();
public Account AccountB = new Account();
}
class Contextimpl : ContextImplementation<Context>
{
public bool Get(string name,Context ctx)
{
return
Implement(@"(Account[AB])Has(\d+)M", (c, e) =>
{
e.ByName<Account>(0,c).Balance = e.Get<int>(1) * 1m;
}).Run(name, ctx) &&
Implement(@"ShouldHave(\d+)MOn(Account[AB])", (c, e) =>
{
e.ByName<Account>(1,c).Balance.ShouldEqual(e.Get<int>(0) * 1m);
}).Run(name, ctx) &&
Implement(@"Transfering(\d+)MFrom(Account[AB])To(Account[AB])",
(c, e) =>
{
e.ByName<Account>(1,c).Transfer(e.Get<decimal>(0) * 1m,
e.ByName<Account>(2,c));
}).Run(name, ctx);
}
}
}
As you might notice, the biggest advantage is that multiple test scenarios can now be implemented since we have created some kind of a context-specific DSL... I'm not very fond of the way you Specify the DSL however; I'll probably need to rethink it.
As always, I'll keep you posted on any progress I make.