Contact

admin

About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

Error retrieving information from external service.
Audioscrobbler/Last.fm

ClustrMap

Page 1 of 1 in the ReSharper category

Machine.Specifications Templates For ReSharper

Posted in BDD | MSpec | ReSharper at Wednesday, 03 March 2010 14:56 W. Europe Standard Time

A couple of days ago Hadi Hariri posted his set of MSpec (Machine.Specifications) templates for ReSharper. ReSharper’s templating system helps you type less repeated code. On top of that, ReSharper templates are much richer when compared to what’s built into Visual Studio. Plus, you edit them with a decent editor instead of hacking XML files.

Like Hadi, I also created a couple of templates specific to MSpec over the course of the last year or so and found them often to reduce the amount of text I have to write. ReSharper Templates are divided into three categories, with at least one MSpec template in each.

Legend

  • foo denotes an editable part of the template
  • | denotes where the cursor will be put upon expansion

File Template

Basically, this is just a new C# file with a single MSpec context in it.

using System;

using Machine.Specifications;

namespace ClassLibrary1
{
  [Subject(typeof(Type))]
  public class When_Context
  {
    Establish context = () => { | };

    Because of = () => { };

    It should_ = () => { };
  }
}

Live Templates (a.k.a. Snippets)

Live Templates provide expansion of keyword-like identifiers. For example cw (Tab) will expand to Console.WriteLine();

Name Expanded
spec A new context, similar to what the File Template above creates.
est Establish context = () => { | };
bec Because of = () => { | };
it It should_observation = () => { | };
fail It should_fail = () => Exception.ShouldNotBeNull(); static Exception Exception;
l () => | ;

Only valid for assignments. For example:

var x = l (Tab) var x = () => | ;
ll () => { | }; Only valid for assignments.

Surround Templates

Surround Templates are useful when you want to wrap a block of code with other code, for example, an if statement (this is one that’s built-in).

Unit testing frameworks almost always have means to assert that are particular test should fail with a specific exception, for example by marking the test method with the ExpectedExceptionAttribute.

The MSpec way of handling/expecting exceptions is to surround the code in Because with Catch.Exception:

public class When_a_negative_amount_is_deducted
{
  static Exception Exception;
  static Account Account;

  Establish context =
    () => { Account = new Account(); };

  Because of =
    () => { Exception = Catch.Exception(() => Account.Deduct(-1)); };

  It should_fail =
    () => Exception.ShouldNotBeNull();
}

There’s a surround template named Catch.Exception that we can make wrap the call to Account.Deduct:

  1. Create the context with just the Account field, Establish and the Because. Select the highlighted code.
    public class When_a_negative_amount_is_deducted
    {
      // Account field and Establish cut for brevity.
    
      Because of =
        () => { Account.Deduct(-1); };
    }
  2. Press the shortcut for ReSharper | Edit | Surround With Template, select "Catch.Exception" from the list of available templates.
    public class When_a_negative_amount_is_deducted
    {
      // Account field and Establish cut for brevity.
    
      Because of =
        () => { Exception = Catch.Exception(() => { Account.Deduct(-1); }); };
    }
  3. Navigate out of the Because field, for example by pressing the (End) key. Type fail (a Live Template, see above) and press (Tab).
    public class When_a_negative_amount_is_deducted
    {
      // Account field and Establish cut for brevity.
    
      Because of =
        () => { Exception = Catch.Exception(() => { Account.Deduct(-1); }); };
      fail(Tab)
    }
  4. Marvel at the amount of code you didn't have to write.
    public class When_a_negative_amount_is_deducted
    {
      // Account field and Establish cut for brevity.
    
      Because of =
        () => { Exception = Catch.Exception(() => { Account.Deduct(-1); }); };
    
      It should_fail =
        () => Exception.ShouldNotBeNull();
    
      static Exception Exception;
    }

Download

ReSharper Type Members Layout for MSpec 0.2

Posted in BDD | ReSharper at Tuesday, 16 September 2008 19:35 W. Europe Daylight Time

A couple of days ago Aaron Jensen released MSpec 0.2, a BDD-style testing framework. Since I got hooked on BDD during my last work project (readable test names!) I was eager giving MSpec a shot. MSpec comes with support for TestDriven.NET so using inside of Visual Studio is a no-brainer once you installed the MSpec support for TD.NET. The release contains everything you need.

Today I wrote my first couple of MSpec specifications and had a very good initial experience. However, there's one caveat with ReSharper's absolute killer feature (well, one of its many killer features): Code Cleanup. I usually like to type code without caring too much about its layout and then do a quick re-format to make it align with my formatting conventions.

ReSharper formatted the specification like this:

[Concern(typeof(StringExtensions), "String testing")]
public class When_a_null_string_is_tested_to_have_a_value : String_testing_specification
{
    Establish context = () => { Sut = null; };

    It it_should_not_hold_a_value = () => HasValue.ShouldBeFalse();

    Because of = () => HasValue = Sut.HasValue();
}

The code structure should follow order in which the specification is run, like so:

[Concern(typeof(StringExtensions), "String testing")]
public class When_a_null_string_is_tested_to_have_a_value : String_testing_specification
{
    Establish context = () => { Sut = null; };

    Because of = () => HasValue = Sut.HasValue();

    It it_should_not_hold_a_value = () => HasValue.ShouldBeFalse();
}

Luckily, ReSharper supports defining a custom type member layout to control in which order members are placed in a reformatted code file. Just add the following lines to ReSharper/Options/Languages/C#/Type Members Layout (uncheck "Use Default Patterns"), under the Patterns element:

<!-- Order Machine.Specifications methods: Members, Establish, Cleanup, Because, It -->
<Pattern>
    <Match>
        <And Weight="100">
            <Kind Is="class"/>
            <HasAttribute CLRName="Machine.Specifications.ConcernAttribute"
                          Inherit="true"/>
        </And>
    </Match>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Or>
                    <Access Is="protected"/>
                    <Static/>
                </Or>
            </And>
        </Match>
    </Entry>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Name Is="context_once"
                      IgnoreCase="true"/>
            </And>
        </Match>
    </Entry>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Name Is="context"
                      IgnoreCase="true"/>
            </And>
        </Match>
    </Entry>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Name Is="after_each"
                      IgnoreCase="true"/>
            </And>
        </Match>
    </Entry>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Name Is="after_all"
                      IgnoreCase="true"/>
            </And>
        </Match>
    </Entry>
    <Entry>
        <Match>
            <And>
                <Kind Is="field"/>
                <Name Is="of"
                      IgnoreCase="true"/>
            </And>
        </Match>
    </Entry>
    <!--All other members-->
    <Entry/>
</Pattern>
Page 1 of 1 in the ReSharper category