Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a method having parameter of interface type

I have the following code:

public BooksInfo GetBookInfo(IBookMarket bookinfo)
{
    // Implementation omitted
}

I can only post the method signature. Now I need to pass a null value as bookinfo and test whether exception is raised or not.

Can someone explain briefly how can I do this unit test using NUnit?

Edit Question:

My Unit Test Code

[TestFixture]

public class FutureTests
{
    //[Test]
    //[ExpectedException(typeof(NullReferenceException),
    // ExpectedMessage = "No value provided!")]
    public void GetPriceData_PassNull_ThrowsException()
    {
        Assert.That(
                () => library.GetPriceData(null),
                Throws.InstanceOf<ArgumentNullException>()
                .With.Property("").EqualTo("pricer"));

    }
}
like image 525
bantu Avatar asked Sep 18 '26 14:09

bantu


2 Answers

There are several possibitities provided by nunit:

Old style

Pre 2.X implementation

[TestFixture]
public class TestGetBookInfo
{
    [Test]
    [ExpectedException(
        ExpectedException = typeof(YourException),
        ExpectedMessage = "Your detailed message",
        MatchType = MessageMatch.Contains)]
    public void TestGetBookInfoException()
    {
        new BookInfoProvider().GetBookInfo(null);
    }
}

New style

Current fluent implementation

[TestFixture]
public class TestGetBookInfo
{
    [Test]
    public void TestGetBookInfo()
    {
        Assert.That(
            () => new BookInfoProvider().GetBookInfo(null),
                Throws.InstanceOf<YourException>()
                    .And.Message.Contains("Your detailed message"));
    }
}

Data driven

Data driven implementation where you could combine cases

[TestFixture]
public class TestGetBookInfo
{
    object[] TestData =
    {
        new TestCaseData(new BookMarketStub()), // "good" case
        new TestCaseData(null).Throws(typeof(YourException)) // "bad" exceptional case
    };

    [Test]
    [TestCaseSource("TestData")]
    public void TestGetBookInfo(IBookMarket bookinfo)
    {
        new BookInfoProvider().GetBookInfo(bookinfo);
        Assert.Pass("all ok"); // this is not necessary
    }
}
like image 66
Akim Avatar answered Sep 20 '26 02:09

Akim


Using NUnit I would go with:

Assert.That(
    () => library.GetBookInfo(null),
    Throws.InstanceOf<ArgumentNullException>());

This code assumes that library is an instance of the type that defined your GetBookInfo method. Also, this approach has considerable advantage over the ExpectedException alternative because it asserts that is really the code under test that is throwing an exception and not the test itself.

It verifies that the method throws an ArgumentNullException because that's the correct exception to throw when you validate a required parameter and it is a null reference. The NullReferenceException should not be thrown programatically by user code.

In this case where the method has only one parameter this may be omitted, but if you want to improve even further your test you could assert that the exception is associated with the parameter in question by doing this:

Assert.That(
    () => library.GetBookInfo(null),
    Throws.InstanceOf<ArgumentNullException>()
        .With.Property("ParamName").EqualTo("bookinfo"));

With this extra assertion your test guarantees that the code is implemented like this (as it should):

public BooksInfo GetBookInfo(IBookMarket bookinfo)
{
    if (bookinfo == null) throw new ArgumentNullException("bookinfo");

    // Implementation omitted
}
like image 35
João Angelo Avatar answered Sep 20 '26 03:09

João Angelo