Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write context/specification style unit tests with an MSTest/xUnit framework?

Tags:

I have been using MSpec to write my unit tests and really prefer the BDD style, I think it's a lot more readable. I'm now using Silverlight which MSpec doesn't support so I'm having to use MSTest but would still like to maintain a BDD style so am trying to work out a way to do this.

Just to explain what I'm trying to acheive, here's how I'd write an MSpec test

[Subject(typeof(Calculator))]     public class when_I_add_two_numbers : with_calculator {   Establish context = () => this.Calculator = new Calculator();   Because I_add_2_and_4 = () => this.Calculator.Add(2).Add(4);   It should_display_6 = () => this.Calculator.Result.ShouldEqual(6); }  public class with_calculator {   protected static Calculator; } 

So with MSTest I would try to write the test like this (although you can see it won't work because I've put in 2 TestInitialize attributes, but you get what I'm trying to do..)

[TestClass] public class when_I_add_two_numbers : with_calculator {    [TestInitialize]    public void GivenIHaveACalculator()    {       this.Calculator = new Calculator();    }     [TestInitialize]    public void WhenIAdd2And4()    {       this.Calculator.Add(2).Add(4);    }     [TestMethod]    public void ThenItShouldDisplay6()    {       this.Calculator.Result.ShouldEqual(6);    } }  public class with_calculator {   protected Calculator Calculator {get;set;} } 

Can anyone come up with some more elegant suggestions to write tests in this way with MSTest?

like image 917
Charlie Avatar asked Jan 13 '11 10:01

Charlie


People also ask

Should I use MSTest or xUnit?

XUnit vs. MSTest is concerned, the biggest difference between xUnit and the other two test frameworks (NUnit and MSTest) is that xUnit is much more extensible when compared to NUnit and MSTest. The [Fact] attribute is used instead of the [Test] attribute.

How do you write xUnit test cases in .NET core?

To write a test you simply create a public method that returns nothing and then decorate it with the Fact attribute. Inside that method you can put whatever code you want but, typically, you'll create some object, do something with it and then check to see if you got the right result using a method on the Assert class.

Can I use xUnit for .NET framework?

On top of that, it works well with ReSharper, Xamarin, TestDriven.Net and a Console runner for accomplishing the Unit test. It includes the excellent extensibility of test classes and test methods. xUnit test is the best Unit testing framework for . Net programming languages like C#, VB.Net, and F#.


2 Answers

What you think about this one:

[TestClass] public class when_i_add_two_numbers : with_calculator {     public override void When()     {         this.calc.Add(2, 4);     }      [TestMethod]     public void ThenItShouldDisplay6()     {         Assert.AreEqual(6, this.calc.Result);     }      [TestMethod]     public void ThenTheCalculatorShouldNotBeNull()     {         Assert.IsNotNull(this.calc);     } }  public abstract class with_calculator : SpecificationContext {     protected Calculator calc;      public override void Given()     {         this.calc = new Calculator();     } }  public abstract class SpecificationContext {     [TestInitialize]     public void Init()     {         this.Given();         this.When();     }      public virtual void Given(){}     public virtual void When(){} }  public class Calculator {     public int Result { get; private set; }     public void Add(int p, int p_2)     {         this.Result = p + p_2;     } } 
like image 91
goenning Avatar answered Sep 18 '22 13:09

goenning


Mark Nijhof has an example of doing Given-When-Then style testing with NUnit in his Fohjin.DDD github repository.

Here's an excerpt from the example referenced above:

public class When_registering_an_domain_event : BaseTestFixture<PreProcessor> {     /* ... */      protected override void When()     {         SubjectUnderTest.RegisterForPreProcessing<ClientMovedEvent>();         SubjectUnderTest.Process();     }      [Then]     public void Then_the_event_processors_for_client_moved_event_will_be_registered()     {         IEnumerable<EventProcessor> eventProcessors;         EventProcessorCache.TryGetEventProcessorsFor(typeof(ClientMovedEvent), out eventProcessors);         eventProcessors.Count().WillBe(1);     } } 

And you can see the Given in the base class implementation:

[Given] public void Setup() {     CaughtException = new NoExceptionWasThrownException();     Given();      try     {         When();     }     catch (Exception exception)     {         CaughtException = exception;     }     finally     {         Finally();     } } 
like image 31
Kaleb Pederson Avatar answered Sep 20 '22 13:09

Kaleb Pederson