Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Behavior-Driven Development with NBehave

, 14 Jan 2009 CPOL
A BDD tutorial using NBehave and MbUnit.
NBehaveTutorialSourceCode.zip
ConsoleApplication1
ConsoleApplication1.4.1.resharper.user
Properties
/* Copyright (C) Dmitri Nesteruk */

using System;

namespace ConsoleApplication1
{
  using NBehave.Narrator.Framework;
  using NBehave.Spec.MbUnit;
  using MbUnit.Framework;

  using That = MbUnit.Framework.TestAttribute;
  using Describe = MbUnit.Framework.CategoryAttribute;
  using For = MbUnit.Framework.CategoryAttribute;
  using Wrote = MbUnit.Framework.DescriptionAttribute;
  using Should = MbUnit.Framework.DescriptionAttribute;
  using Full = MbUnit.Framework.MultipleAssertsAttribute;

  [
    Author("Dmitri", "dmitrinesteruk@gmail.com"),
    Wrote("Account operation tests"),
    TestsOn(typeof(Account)),
    For("Banking system")
  ]
  public class AccountTest : SpecBase
  {
    public Account account;
    public Account account2;

    [SetUp]
    public void Initialize_before_each_test()
    {
      account = new Account();
      account2 = new Account { Balance = 100 };
    }

    [Full, Story, That, Should("Increase account balance when money is deposited")]
    public void Deposit_should_increase_account_balance()
    {
      Story story = new Story("Deposit");
      story.AsA("User")
        .IWant("The bank account balance to increase by the amount deposited")
        .SoThat("I can deposit money");

      story.WithScenario("Money deposit")
        .Given("My bank account is empty", () => { account.Balance = 0; })
        .When("I deposit 100 units", () => account.Deposit(100))
        .Then("The account balance should be 100", () => account.Balance.ShouldEqual(100));

      story.WithScenario("Negative amount deposit")
        .Given("My bank account is empty", () => { account.Balance = 0; })
        .When("I try to deposit a negative amount", () => { })
        .Then("I get an exception",
              () => typeof(Exception).ShouldBeThrownBy(() => account.Deposit(-100)))
        .And("My bank account balance is unchanged",
             () => account.Balance.ShouldEqual(0));
    }

    [Story, That, Should("Decrease account balance when money is withdrawn")]
    public void Withdrawal_should_decrease_account_balance()
    {
      Story story = new Story("Withdrawal");
      story.AsA("User")
        .IWant("To be able to withdraw money if I have it")
        .SoThat("I can buy things");

      story.WithScenario("Withdrawal with empty bank account")
        .Given("My bank is empty", () => { account.Balance = 0; })
        .When("I try to withdraw money", () => {})
        .Then("I get an exception", () =>
              typeof(Exception).ShouldBeThrownBy(() => account.Withdraw(100)))
        .And("I still have an empty bank account", () => account.Balance.ShouldEqual(0));

      story.WithScenario("Withdrawal with sufficient balance")
        .Given("I've got 100 dollars in my bank account", () => { account.Balance = 100; })
        .When("I try to withdraw 50 dollars", () => account.Withdraw(50))
        .Then("I have 50 dollars left in the account",
              () => account.Balance.ShouldEqual(50));
    }

    [Story, That, Should("Transfer money from one account to another")]
    public void Transfer_should_move_money_from_one_account_to_another()
    {
      Story story = new Story("Tranfer");
      story.AsA("User").IWant("The transfer feature to be atomic")
        .SoThat("My money isn't lost");

      story.WithScenario("Valid transfer")
        .Given("I have 100 dollars", () => { account.Balance = 100; })
        .And("You have 100 dollars", () => { account2.Balance = 100; })
        .When("I give you 50 dollars",
              () => Assert.DoesNotThrow(() => Account.Transfer(account, account2, 50)))
        .Then("I have 50 dollars left", () => account.Balance.ShouldEqual(50))
        .And("You have 150 dollars", () => account2.Balance.ShouldEqual(150));
    }
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dmitri Nеstеruk
Founder ActiveMesa
United Kingdom United Kingdom
I work primarily with the .NET technology stack, and specialize in accelerated code production via code generation (static or dynamic), aspect-oriented programming, MDA, domain-specific languages and anything else that gets products out the door faster. My languages of choice are C# and F#, though I'm open to suggestions.
 
I'm a Microsoft MVP (Visual C#) since 2009. I run a collective tech blog at DevTalk.net. I use my own editor called TypograFix to typeset articles and blog posts.
 
Like the article and want this implemented in your product? Got a project that can benefit from Microsoft.Net goodness? Then get in touch!
Follow on   Twitter

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411023.1 | Last Updated 14 Jan 2009
Article Copyright 2009 by Dmitri Nеstеruk
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid