Showing posts with label NUnit. Show all posts
Showing posts with label NUnit. Show all posts

Wednesday, 21 November 2012

TestCaseData mock verifications

It is common practice to use an the TestCaseSource attribute to specify test data and the expected result in the format of IEnumerable<TestCaseData> like the example below.

[Test, TestCaseSource("TestCases")]
public int ShouldReturnTheExpectedValueWhenCalled(int testCase)
{
 context.Setup(c => c.Number).Returns(testCase);

 return context.CalculateSomething();
}

private IEnumerable<TestCaseData> TestCases
{
 get
 {
  yield return new TestCaseData(4).Returns(16);
  yield return new TestCaseData(5).Returns(25);
  yield return new TestCaseData(-1).Throws(typeof( Exception));
 }
}

For some tests the method shown above is sufficient but what about when you are testing a method that does not return a value and executes a command? In this circumstance you will be using mocking to assert that the method is operating correctly. The only problem with this is that I could not find any documentation for using a mock verification with TestCaseData, but I was able to get the functionality required from the example below.

[Test, TestCaseSource(&quot;TestCases&quot;)]
public void ShouldAlwaysCallSaveMethod(int testCase, Action[] verifications)
{
 // Act
 context.DoSomething(testCase);

 // Assert
 foreach (var verification in verifications)
 {
  verification.Invoke();
 }
}

private IEnumerable&lt;TestCaseData&gt; TestCases
{
 get
 {
  yield return new TestCaseData(random.Next(), 
   new Action[] 
   {
    () =&gt; service.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Once()),
    () =&gt; service2.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Once())
   });

  yield return new TestCaseData(0,
   new Action[]
   {
    () =&gt; service.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Once()),
    () =&gt; service2.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Never())
   });

  yield return new TestCaseData(-(random.Next()), 
   new Action[]
   {
    () =&gt; service.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Never()),
    () =&gt; service2.Verify(s =&gt; s.SomeAction(It.IsAny<int>()), Times.Never())
   });
 }
}

Sunday, 9 September 2012

Unit testing snippets

The boilerplate code for unit tests can be the longest part of writing tests and if it isn't the longest part, it is almost always the most boring part! I have created my own NUnit snippets to help save time and keystrokes, I am going to talk about these macros in this post.


Test Fixtures


  
    
NUnit test fixture nunitfixture NUnit test fixture in C# Danny Kendrick Expansion
testfixturename testfixturename testfixturename

The key things from the snippet above are

  • Shortcut - This element is how you will call the snippet in Visual Studio
  • Literal section - These elements are describing any literal values that the user will specify once the snippet is generated.
  • Code - This element is where the code that will be generated is placed. To specify where the literal values will be placed use the syntax $variable$ as shown in the snippet.
Once you have loaded the snippet into visual studio, the snippet can be generated by typing in the shortcut and hitting tab.

nunitfiture

Will turn into the code below, with the testfixturename text highlighted by Visual Studio for replacement by the user.

[TestFixture]
public class testfixturename
{
    [SetUp]
    public virtual void SetUp()
    {
    }

}

Test Fixtures

The next snippet is used to generate the tests themselves with comments for arrange, act and assert (the three A's of unit testing).



    
        
NUnit test nunittest NUnit test method in C# Danny Kendrick Expansion
outcome outcome outcome condition condition condition

This snippet will generate following code with outcome and condition highlighted by Visual Studio for replacement.

[Test]
public void Should_outcome_When_condition()
{
    // Arrange
 
    // Act
 
    // Assert
}

Test Fixtures

The last snippet I am going to talk about in this post is one I use for testing that an argument null exception is thrown correctly. This is important for me as I don't believe that the object should be create-able unless it's prerequisites are met. But this snippet could easily be modified for any type of exception.



  
    
NUnit ArgumentNullException nunitargnull NUnit test method that throws ArgumentNullException in C# Danny Kendrick Expansion
parameter parameter parameter

This snippet will generate following code with parameter highlighted by Visual Studio for replacement.

[Test, ExpectedException(typeof(ArgumentNullException), ExpectedMessage = "Value cannot be null.\r\nParameter name: parameter")]
public void ShouldThrowAnExceptionWhenparameterIsNull()
{
    // Act
}

Summary

Hopefully the snippets described in this post can help speed up your unit test development creation times as they have done with mine. Leaving the important part of the tests for me to fill in. To read more about creating Visual Studio snippets there is heaps of information on MSDN.

Monday, 13 August 2012

Reflection in unit tests

The idea of using reflection to generate unit test for factories came to me while attempting to write simple unit tests for a factory class. The aim was to ensure that any changes to the class in future did not break my code, I started with something like the code below:

[TestFixture]
public class BlogExampleTests
{
 private TransactionFactory factory;

 [SetUp]
 public void SetUp()
 {
  factory = new TransactionFactory();
 }

 [Test]
 public void ShouldCorrectlyReturnTransactionA()
 {
  ITransaction transaction = null;
  Assert.DoesNotThrow(() => transaction = factory.GetTransactionA());

  Assert.IsNotNull(transaction);
 }

 [Test]
 public void ShouldCorrectlyReturnTransactionB()
 {
  ITransaction transaction = null;
  Assert.DoesNotThrow(() => transaction = factory.GetTransactionB());

  Assert.IsNotNull(transaction);
 }

 [Test]
 public void ShouldCorrectlyReturnTransactionC()
 {
  ITransaction transaction = null;
  Assert.DoesNotThrow(() => transaction = factory.GetTransactionC());

  Assert.IsNotNull(transaction);
 }
}

Technically this works but I expect the factory to have approximately 200 methods when completed, so to get full coverage would be 200 test methods as well. The next move to improve these tests was to move all of these to one method using an array/list of delegates and pass the list into the test method like below:

public delegate ITransaction MyDelegate();

[TestFixture]
public class BlogExampleTests
{
 private static readonly TransactionFactory Factory = new TransactionFactory();
 private static object[] delegates = new[]
  {
   new MyDelegate(Factory.GetTransactionA),
   new MyDelegate(Factory.GetTransactionB),
   new MyDelegate(Factory.GetTransactionC)
  };

 [Test, TestCaseSource("delegates")]
 public void ShouldCorrectlyReturnTheTransactions(MyDelegate method)
 {
  ITransaction transaction = null;
  Assert.DoesNotThrow(() => transaction = method.Invoke());

  Assert.IsNotNull(transaction);
 }
}

This solution above is better than the first solution, although it still requires a new delegate to be created every time a method is added to the factory class. Then the idea occurred to me that not only could I save myself a lot of keystrokes but also ensure that the convention of the factory is followed in future by using reflection to look at the class and get all of the methods.

[TestFixture]
public class BlogExampleTests
{
 private TransactionFactory factory;
 private static readonly Type FactoryType = typeof(TransactionFactory);

 [SetUp]
 public void SetUp()
 {
  var parameters = new Type[0];
  var constructor = FactoryType.GetConstructor(parameters);
  factory = (TransactionFactory)constructor.Invoke(new object[0]);
 }

 [Test]
 public void ShouldBeAbleToCreateAllTypes([ValueSource("GetFactoryTransactions")] MethodInfo method)
 {
  ITransaction transaction = null;

  Assert.DoesNotThrow(() => transaction = method.Invoke(factory, null) as ITransaction);
  Assert.IsNotNull(transaction);
 }

 IEnumerable GetFactoryTransactions()
 {
  return FactoryType.GetMethods(
   BindingFlags.Instance | 
   BindingFlags.Public | 
   BindingFlags.DeclaredOnly);
 }
}

In summary when someone adds or modifies the transaction factory it will automatically test that method and in this case ensure that the method does not require any parameters. Another good usage of unit tests using reflection is ensuring that every implementation that uses a certian interface (i.e. IDomainService) can be resolved using dependency injection.