65.9K
CodeProject is changing. Read more.
Home

A New BDD Framework in .NET: NetSpec => Aubergine

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0 vote)

Nov 12, 2009

CPOL
viewsIcon

7551

A new BDD Framework in .NET: NetSpec =>Aubergine

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.