bgeek.net

OAuth MVC.net Revisited

Posted by Owen Evans on Tuesday, March 3rd, 2009

My Foray into OAuth with MVC.net is getting more thorough. I quickly came upon a problem in the project as it stood with regards to the signing methods I’d used.

I’d grabbed the OAuth base class from the samples available over on oauth.net but quickly found out (well actually not that quickly, I still had to [...]

continue reading

Back out of black

Posted by Owen Evans on Monday, February 23rd, 2009

The controversial (to say the lease) piece of rubbish legislation that is Section 92A has been delayed by parliament due somewhat to the presure we put on government through protests etc.

It’s not over but this is the first sign that anyone’s actually listening.

More here Sphere: Related Content

continue reading

Added a sample OAuth consumer in Cocoa

Posted by Owen Evans on Saturday, February 21st, 2009

Well this is my first foray into the world of objective-c programming, but I’ve added a sample consumer for mac os x to the ms-mvc OAuth project, I know it’s not mvc specific (I’m going to write an mvc consumer next) but as I program on my Mac it was useful for me to have [...]

continue reading

NSpecify => RSpec… well closer anyway

Posted by Owen Evans on Thursday, February 14th, 2008

So as I’ve been doing some Ruby+Rails work recently, I’ve become very enamoured of Rspec, it’s ability to turn plain text tests into runable tests is awesome.

I love that I can run this as an automated test:

Story: News Page

As a visitor I Want to go to the news site So that I can keep up with all the latest news

Scenario: A visitor goes to the news site and one post exists Given a news_post named ‘Test News Post’ exists with content ‘This is a news post created for the scenario’ When visitor goes to the home page And clicks on ‘News’

Then visitor should see the news show page And page should include a notice ‘Test News Post’ And page should have the news post’s name, and content

it’s really awesome to see this kind of feature, and makes testing in C# pale in comparison… however, there is also the syntax of RSpec that I’m getting used to that allows you to write specifications that look like this:

require File.dirname(FILE) '/../spec_helper'

describe User, "A new user" do before(:each) do @user = User.new end

it "should be able to retain email address" do email = "email" @user.email = email @user.email.should be_equal(email) end

it "should be able to retain password" do password = "password" @user.password = password @user.password.should be_equal(password) end

it "should not be valid for save" do @user.shouldnot bevalid end

it "should require an email address" do login = "login" password = "password" @user.password = password @user.passwordconfirmation = password @user.login = login @user.shouldnot be_valid end

it "should require a password" do login = "login" email = "email" passwordconfirm = "password" @user.email = email @user.passwordconfirmation = passwordconfirm @user.login = login @user.shouldnot be_valid end

it "should require a password confirmation" do login = "login" email = "email" password = "password" @user.email = email @user.login = login @user.password = password @user.shouldnot bevalid end

it "should require a login" do email = "email" password = "password" @user.email = email @user.password = password @user.passwordconfirmation = password @user.shouldnot be_valid end

it "should be valid if login, email password and password confirmation are provided" do login = "login" email = "email" password = "password" @user.password = password @user.passwordconfirmation = password @user.login=login @user.email = email @user.should bevalid end

it "should only be valid if password and password confirmation match" do login = "login" email = "email" password = "password" @user.password = password @user.passwordconfirmation = password "not the same" @user.login=login @user.email = email @user.shouldnot be_valid end

it "should not be valid if password and password confirmation are under 4 characters" do login = "login" email = "email" password = "pas" @user.password = password @user.passwordconfirmation = password @user.login=login @user.email = email @user.shouldnot be_valid end

it "shouldn't be valid if the same login name and email exist already" do login = "login" email = "email" password = "password" @user.password = password @user.passwordconfirmation = password @user.login=login @user.email = email @user.save @user = User.new @user.password = password @user.passwordconfirmation = password @user.login=login @user.email = email @user.shouldnot bevalid end

after(:all) do User.delete_all end

end

describe User, "A saved user" do before(:all) do @initialpassword = "password" login = "login" user = User.new(:login => login,:password=>@initialpassword,:passwordconfirmation=>@initialpassword,:email=>"email") user.save @user = User.findbylogin(login) end

it "should encrypt the password" do @user.password.shouldnot equal(@initialpassword) end

after(:all) do @user.destroy end end

which gives you an output like this:

User A saved user - should encrypt the password

User A new user - shouldn’t be valid if the same login name and email exist already - should not be valid if password and password confirmation are under 4 characters - should only be valid if password and password confirmation match - should be valid if login, email password and password confirmation are provided - should require a login - should require a password confirmation - should require a password - should require an email address - should not be valid for save - should be able to retain password - should be able to retain email address

Finished in 0.594 seconds

12 examples, 0 failures

It would be great to have this in my C# world as well, but hey I’ve got to work within the boundaries of NUnit, due to the fact that there are other members on the team too and they aren’t as grounded in BDD and TDD as I am.

There is one thing however that I did want to add, and that’s syntax that makes people get away from the idea that Unit tests always have to be about specifying code, and can be more about specifying the behaviour.

I went to work on NSpecify, as the NUnit add-on is easy and seamless to install, everyone on my team can run it, as it’s in with their code under source control (this allows Continuous integration without too many hassles of versioning and setup etc.).

As such I modified NSpecify to add in [Context] to define a “test case” [BeforeAll] to define a “TestFixtureSetUp”, [BeforeEach] to define a “SetUp” [AfterAll] to define a “TestFixtureTearDown” and [AfterEach] to define a “TearDown”.

These are all synonyms so they can be used interchangeably with the existing attributes.

Also I added the ability to have more complex collection matching.

want to specify that a collection of users has a user with a certain Name attribute?

easy:

Specify.That(UserCollection).Must.Contain((User user)=>user.Name==expectedName);
Also I added the ability to define expected exceptions on Method calls, but based on Lambdas (as the above is)
Specify.That(() => { MethodThatThrowsACustomException(); }).Must.Be.Disallowed(typeof(CustomException)).WithMessage(%u201CThis method is disallowed in this context%u201D);
the with message is optional, without it the specification will just match the type of exception without much more.

Next I’m going to put in some negative collection matching like above, and also add in the NUnit.Spec extension methods, but make them throw specification exceptions, as just using them out of the box means that the test shows green in NUnit even thought there’s an exception thrown.

So at the moment I can do this:

[Context]
public class SaveCustomerFunctionalityWithAlternativeSyntax
{
    private Customer customer = null;

[BeforeAll]
public void FunctionalitySetup()
{

}

[BeforeEach]
public void SpecificationSetup()
{
    customer = new Customer(123);
}

[Specification("The customer id's should be equal")]
public void LoadCustomer()
{
    Specify.That(customer.Id).Must.Equal(123, "The customer id's aren't equal");
}

[Specification("The customer id's should be equal")]
public void LoadCustomerFailed()
{
    Specify.That(customer.Id).Must.Not.Equal(125, "The customer id's aren't equal");
}

[AfterEach]
public void SpecificationCleanup()
{
    customer = null;
}

[AfterAll]
public void FunctionalityCleanup()
{

}

}

but I want to get to the point where I can do this
   [Context]
public class WhenANewUserIsCreated
{
    User user;
    [BeforeEach]
    public void CreateTheNewUser()
    {
        user = new User();
    }

[Specification]
public void TheUserShouldBeMarkedAsNew()
{
    user.IsNew.Must.Be.True();
}

[Specification]
public void TheUserShouldNotBeAllowedToBeSaved()
{
    user.Must.Not.Allow(user.Save).With.Error("A user must have a name before being saved");
}

}

Attached is the patch:

Context+MethodDissalowed+ComplexMatchingDelegates.patch

Just be aware of a couple of things

  • I’ve updated NUnit to 2.4.6
  • The lambda expressions above rely on .net 3.5 so VS2008 is a must.
Enjoy

Technorati Tags: ,,,,

Sphere: Related Content

Posted in: [||||].

kick it on DotNetKicks.com

Shout it

Viewing 1 Comment

    • ^
    • v
    Firstly, I'd like to thank you for your contributions to the NSpecify project. I really like the Context, BeforeEach, etc synonyms that you've added. The lambda support you've added is also pretty cool.

    In the future I plan to introduce extension methods to allow specifying on the object itself. I actually did a prove of concept a while back. The problems I found was that you can't have the following syntax

    user.Must.Not.Allow(user.Save).With.Error("A user must have a name before being saved");

    but rather as follows

    user.Must().Not.Allow(user.Save).With.Error("A user must have a name before being saved");

    which I don't mind.

    I'm working on a Auto Test library and Notifier application. I have an almost stable version and if you are interested, let me know. With this application I plan to have the same sort of specdoc to be displayed (as in rspec on TextMate). Maybe in the browser, I'll see when I get there...

    My only problem at the moment is I'm stuck in .NET 2.0 land in my day job, so my understanding and exploration of 3.5 features suffers at the moment...
 

Trackbacks

(Trackback URL)

close Reblog this comment
blog comments powered by Disqus