Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I understand how exceptions work and how to catch and handle them in C# but how can I simulate events that may cause an exception to ensure that it is caught correctly? For example, is it possible to run an application in a kind of test bed where it's possible to simulate network problems, database problems, etc? Exceptions by their nature seem hard to reproduce thus making it hard to ensure your code can cope with them.

Although I mainly develop using C#/.NET/Visual Studio, answers or resources relating to other languages could be useful.

share|improve this question
    
Another possible solution is described in this MSDN article: Fault Injection Testing with TestApi –  Giorgi Feb 8 '11 at 17:04
add comment

4 Answers

up vote 11 down vote accepted

1) If you followed the dependency injection model, you could substitute real implementations of certain parts with the mocks which would throw exceptions as you need them. That would however require of you to initially design your application in a specific way or completely reengineer it.

Like:

public class SqlUsersRepository : IUsersRepository
{
    public void RegisterNewUser (User newUser)
    {
        throw new SqlException ("Connection timeout");
    }
}

Here however we would have the problem that the consumer code shouldn't concern itself with handling concrete implementation exceptions.

2) Another approach is to replace certain method calls with your custom wrappers.

Instead of:

FileStream fs = File.OpenRead (path);

you use:

FileStream fs = File.OpenRead_Test (path);

by providing a custom extension method (just a quick idea):

public static FileStream OpenRead_Test (this System.IO.File file, string path)
{
    throw new FileNotFoundException ();
}
share|improve this answer
add comment

You need to look at mocking frameworks.

With these you use dependency injection to call the fake database (say) rather than the real one. This means that you have total control over what gets returned for each call.

You then set up a test that when called simply throws the desired exception:

public void Test1()
{
    throw new NullArgumentException();
}

Your test passes when your code handles this correctly.

share|improve this answer
add comment

Mocking and injection can only get you so far and require big changes in approach in some cases.

If you don't want to redesign your app to fit a testing framework then what you really need is a host or environment rigged for errors. There are many ways to simulate network slowness our outage (even Microsoft test tools have a little of this in the web testing area). I have had best success with putting machines behind a router that can be tampered with to change simulations in coordination with a database set to produce errors and scripts to change the errors the database produces.

Even with that if you go fast enough or far enough down toward the hardware there are errors like concurrency issues and delayed write failures that you pretty much cannot simulate. Sometimes you have to cause them for real and other times you just have to work without the safety net.

share|improve this answer
    
Agreed - in some cases, you can't afford the overheads from dependency injection in your release code, for example. Not an everyday issue, but it can happen. –  Steve314 Feb 8 '11 at 17:11
add comment

I once used a tool called Cantata IIRC, which could extract chunks of your code, substitute calls to autogenerated mocks, and capture parameters from calls using a script to provide the results from the mock.

Trouble is, that was in the mid 90s, and it was for C++.

I have little idea what tool support is available for unit testing now, though I imagine it costs.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.