Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate throwing an exception in Unit tests?

How can I simulate an exception being thrown in C# unit tests?

I want to be able to have 100% coverage of my code, but I can't test the code with exceptions that may occur. For example I cannot simulate a power faluire that may occur.

For example:

public void MyMethod()
{  
  try
  {  
  ...  
  }  
  catch(OutOfMemoryException e)
  {
  ...
  }  
  catch(RandomErrorFromDatabaseLayer e)
  {
  ...
  }  
}

I want to be able to simulate any kind of exception that is in this method and should be caught.
Are there any libraries that may help me in this matter?

Edit 1: Any help in accomplishing what I asked with Moq?

like image 540
radu florescu Avatar asked Jan 13 '12 13:01

radu florescu


2 Answers

You need to create a mock object that stands in for the real objects that can throw these exceptions. Then you can create tests that simply are something like this:

public void ExampleMethod()
{
    throw new OutOfMemoryException();
}

If you are using a dependency injection framework it makes replacing the real code with the mock code much easier.

like image 87
ChrisF Avatar answered Nov 15 '22 06:11

ChrisF


What you need is stub - an object that will simulate certain conditions for your code. For testing purposes, you usually replace real object implementation with stub (or other type of faked object). In your case, consider:

public class MyClass
{
    private IDataProvider dataProvider;

    public void MyMethod()
    {
        try
        {
            this.dataProvider.GetData();
        }
        catch (OutOfMemoryException)
        {
        }
    }
}

Now, class you are testing should be configurable at some level - so that you can easily replace real DataProvider implementation with stubbed/faked one when testing (like you said, you don't want to destroy your DB - nobody wants!). This can be achieved for example by constructor injection (or in fact, any other dependency injection technique).

Your test then is trivial (some made-up requirement to test when exception is thrown):

[Test]
public void MyMethod_DataProviderThrowsOutOfMemoryException_LogsError()
{
    var dataProviderMock = new Mock<IDataProvider>();
    dataProviderMock
        .Setup(dp => dp.GetData())
        .Throws<OutOfMemoryException>();
    var myClass = new MyClass(dataProviderMock);

    myClass.MyMethod();

    // assert whatever needs to be checked
}
like image 35
k.m Avatar answered Nov 15 '22 04:11

k.m