Click here to Skip to main content
12,242,449 members (56,378 online)
Click here to Skip to main content

Stats

55.6K views
340 downloads
81 bookmarked
Posted

Behavior-Driven Development with NBehave

, 14 Jan 2009 CPOL
A BDD tutorial using NBehave and MbUnit.
/* 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!

You may also be interested in...

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