How to simulate throwing an exception in Unit tests? - c#

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?

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.

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
}

Related

how to pass types into test method

How can I pass types into my unit tests?
public void MethodUnderTest()
{
try
{
var businessService = _businessService.DoWork();
}
catch (SomeException exception)
{
//do some stuff
}
catch (SomeOtherException exception)
{
//do other stuff
}
}
My unit test should be something like this:
[TestCase(typeof(SomeException))]
[TestCase(typeof(SomeOtherException))]
public void UnitTest(Exception exception)
{
_businessService.Setup(x=>x.DoWork).Throws.InstanceOf<exception>();
//verify that when we called DoWork, that the logic inside of one of the catches was executed
}
One way this can be implemented would be, by utilizing inferred generics ..
you will have a test case source in your test fixture.
public static List< Exception > Exceptions => new List< Exception >
{
new InvalidOperationException(),
new OverflowException()
};
and then modify your unit test method as :
[Test]
[TestCaseSource(nameof( Exceptions ))]
public void UnitTest<T>( T exception ) where T : Exception, new(){
_businessService.Setup(x=>x.DoWork).Throws.InstanceOf<T>();
//verify that when we called DoWork, that the logic inside of one of the catches was executed
}
Then the code would infer the types from the instance of the exceptions in the test case source. I can't think of a way to do this with out instantiating the exceptions ...
You haven't said what you have tried that didn't work. On the surface, it appears easy enough, but perhaps I don't understand what you want to do.
The example unit test you show is incorrect. It takes an Exception as an argument, but you are giving it a Type. Based on your title, the test method should accept a type. Then do something like...
[TestCase(typeof(SomeException))]
[TestCase(typeof(SomeOtherException))]
public void UnitTest(Type exceptionType)
{
Assert.That(()=>_businessService.Setup(x=>x.DoWork),
Throws.InstanceOf(exceptionType));
}
```
Did I misunderstand the problem?

Checking a private field vs catching an exception

I have a class from a third-party assembly (so I can't edit it):
public class MyClass
{
private bool _loggedIn;
public void Login() {_loggedIn = true;}
public void Logout() {
if (!_loggedIn) throw new InvalidOperationException();
_loggedIn = false;
}
}
Now, suppose I have an instance of MyClass (for which I don't know _loggedIn), and I need call LogOut. Which of the following methods of avoiding a fatal exception will generally be faster? (any other method would be fine too):
To call LogOut, and if _loggedIn == false, just catch the exception
To use reflection to check that _loggedIn == true, and only call LogOut if so
It depends on the invariants you expect to see in your application.
1. If you expect to have a lot of MyClass having different state(logged in, logged off), then it is better to avoid overhead of exception (because exception is Exceptional situation) and use some specific public IsLoggedIn property (obviously to avoid Reflection) or some TryXxxxx-like methods.
And even if you can't modify the original code no one stops you from wrapping it:
public class MyWrappedClass
{
public Boolean IsLoggedIn {get; private set;}
private MyClass m_Log;
public MyWrappedClass ()
{
this.m_Log = new MyClass();
this.IsLoggedIn = false;
}
public void Log()
{
try
{
this.m_Log.LogIn();
this.IsLoggedIn = true;
}
catch
{
this.IsLoggedIn = false;
}
}
public void LogOut()
{
try
{
this.m_Log.LogOut();
this.IsLoggedIn = false;
}
catch
{
this.IsLoggedIn = true;
}
}
}
You could even go further and implement IDisposable interface with it to avoid manual LogIn-LogOut management:
public class MyWrappedClass
{
private class LogSessionToken : IDisposable
{
private MyWrappedClass parent;
public LogSessionToken (MyWrappedClass parent)
{
parent.LogIn();
}
public void Dispose()
{
parent.LogOut();
}
}
public IDisposable LogSession()
{
return new LogSessionToken (this);
}
// ...
}
And use it like
using (var logToken = wrappedInstance.LogSession)
{
// do the work.
} // No need to worry about manual LogOut
2. If you expect to use only few of MyClass in a proper fashion, then it would be a better idea to not handle exception at all - if something wrong happened then it is some programming error thus the program shall be terminated.
First, if your class doesn't expose at least a read-only property for LoggedIn, there sounds like a fairly large design flaw.
For speed, using reflection will generally be faster, particularly if you cache the FieldInfo or build a Func<bool> using System.Linq.Expressions. This is because Exceptions collect lots of debug information when thrown, including a StackTrace, which can be expensive.
As with anything, though, it is often best to test such operations, as there are sometime optimizations or other factors that may surprise you.
If the pattern if (CanFoo) Foo(); appears very much, that tends to imply very strongly that either:
A properly-written client would know when it can or cannot call Foo. The fact that a client doesn't know suggest that it's probably deficient in other ways.
The class exposing CanFoo and Foo should also expose a method which will Foo if possible and appropriate (the method should throw if unable to establish expected post-conditions, but should return silently if the post-conditions were established before the call)
In cases where a class one does not control should provide such a method but doesn't, the cleanest approach may be to write one's own wrapper method whose semantics mirror those the missing method should have had. If a later version of the class implements the missing method, changing one's code to use that implementation may be easier than refactoring lots of if (CanFoo) constructs.
BTW, I would suggest that a properly-designed class should allow calling code to indicate whether it is expecting a transition from logged-in state to logged-out state, or whether it wants to end up in logged-out state but it doesn't care how it gets there. Both kinds of semantics have perfectly legitimate uses; in cases where the first kind would be appropriate, having a LogOut method throw an exception if called on a closed session would be a good thing, but in cases where client code merely wants to ensure that it is logged out, having an EnsureLoggedOut method that could be invoked unconditionally would be cleaner than having to add extra client-side code for that purpose.

Asynchronous initialization and its unit testing

Background
I need some class to perform background initialization, which should start in constructor. Currently I'm using a Task which is started by constructor, and then all operations, depending on that initialization wait for that Task completion.
Please take a look at the following simplified example:
interface IEntry {}
interface IRepository
{
IQueryable<IEntry> Query { get; }
void Add(IEntry entry);
}
class PrefetchedRepository : IRepository
{
private readonly Task _prefetchingTask;
private readonly ICollection<IEntry> _entries = new List<IEntry>();
private readonly IRepository _underlyingRepository;
public PrefetchedRepository(IRepository underlyingRepository)
{
_underlyingRepository = underlyingRepository;
// Background initialization starts here
_prefetchingTask = Task.Factory.StartNew(Prefetch);
}
public IQueryable<IEntry> Query
{
get
{
EnsurePrefetchCompleted();
return _entries.AsQueryable();
}
}
public void Add(IEntry entry)
{
EnsurePrefetchCompleted();
_entries.Add(entry);
_underlyingRepository.Add(entry);
}
private void EnsurePrefetchCompleted()
{
_prefetchingTask.Wait();
}
private void Prefetch()
{
foreach (var entry in _underlyingRepository.Query)
{
_entries.Add(entry);
}
}
}
This works. The problem starts when I want to test initialization in Unit Test. I'm creating the instance and providing the mock of underlying repository. I want to ensure that all entries were fetched from the mock as expected.
[TestFixture]
public class PrefetchingRepositoryTests
{
[Test]
public void WhenInitialized_PrefetchingIsDone()
{
// Arrange
var underlyingRepositoryMock = A.Fake<IRepository>();
// Act
var target = new PrefetchedRepository(_underlyingRepository);
// Assert
underlyingRepositoryMock.CallsTo(r => r.Query).MustHaveHappened(Repeated.Exactly(1));
}
}
As you can imagine, most of the time fails, because actually initialization didn't started yet at the assertion point.
Questions
Question 1 - Initialization: Is there more elegant way of asynchronous initialization rather than starting task in constructor and waiting for it in all dependent operations?
Question 2 - Testing: I thought of 2 possible ways to solve race between the test and testee:
Using event handle to the test:
[Test]
public void WhenInitialized_PrefetchingIsDone()
{
// Arrange ...
var invokedEvent = new ManualResetEvent(false);
underlyingRepositoryMock.CallsTo(r => r.Query).Invokes(_ => invokedEvent.Set());
// Act ...
// Assert
Assert.True(invokedEvent.WaitOne(1000));
}
Exposing EnsurePrefetchCompleted method as internal and using it in the Unit Test (assuming usage of [assembly: InternalsVisibleTo("...")])
The problem with both solutions is that in case of failure time duration long (actually in the second case - it is limited by test timeout).
Is there any simpler way to do this kind of testing?
Extract the prefetch logic into a separate Prefetcher class and when testing mock the Prefetcher with something that does the fetching without the use of a separate thread.
This will allow you to do the white-box testing of your PrefetchedRepository which I see you are attempting to do with
underlyingRepositoryMock.CallsTo(r => r.Query).MustHaveHappened(Repeated.Exactly(1)); (I would never do white-box testing, but that's just me.)
Once you are done with your white box testing, you can then do black-box testing of your PrefetchedRepository, without concern as to how it works internally. (Whether it invokes other objects to do its job, how many times it invokes them, etc.) Therefore, your testing code will not need to guess the point in time when it is okay to check whether query has been invoked, because it will not be concerned at all with whether query was invoked or not. Essentially, your testing code will be testing against interface IRepository, not against class PrefetchedRepository.
Don't expose a instance which is in invalid state. Client code may often notice a delay when calling any members in PrefetchedRepository just because the underlying repository is slow. You're trying to be clever by hiding these details by hiding all the grotty waiting logic inside EnsurePrefetchCompleted which client code doesn't even know. But this may surprise the client why does even this takes a lot of time??
Better approach is to expose the Task in the public surface of the API and let the client code await it before it does anything with the repository instance.
Something like this:
class PrefetchedRepository : IRepository
{
private readonly Task _prefetchingTask;
private readonly ICollection<IEntry> _entries = new List<IEntry>();
private readonly IRepository _underlyingRepository;
public PrefetchedRepository(IRepository underlyingRepository)
{
_underlyingRepository = underlyingRepository;
// Background initialization starts here
_prefetchingTask = Task.Factory.StartNew(Prefetch);
}
public Task Initialization
{
get
{
return _prefetchingTask;
}
}
...
}
Then you could do
var repo = new PrefetchedRepository(someOtherSlowRepo);
await repo.Initialization;
//Then do whatever with the repo.
Of course delete that EnsurePrefetchCompleted method and all calls to it.
But I do understand this introduces the smell so-called Temporal Coupling.
Better design is to introduce a Factory which does this for you.
public class PrefetchedRepositoryFactory
{
public Task<IRepository> CreateAsync()
{
//someOtherSlowRepo can be a parameter or instance field of this class
var repo = new PrefetchedRepository(someOtherSlowRepo);
await repo.Initialization;
return repo;
}
}
Then you could simply do
var repo = await prefetchedRepositoryFactory.CreateAsync();
//Do whatever with repo.
If you do so, you don't have to take any special care for testing as you'll always have the fully constructed repository in hand.
You can await inside the Test methods; Most of the major unittesting frameworks supports async Task returning methods.

ExpectedException in NUnit SetUp

I'm using NUnit and Rhino Mocks. I use the AAA-syntax and I do the Arrange and Act in the setup method, and every Test method is an Assert.
[TestFixture]
public class When_subSystem_throws_exception
{
SomeClass subject; // System under test
[SetUp]
public void Setup()
{
// Arrange
IDependency dependency = MockRepository.GenerateStub<IDependency>();
dependency.Stub(m => m.DoStuff()).Throw(new Exception()); // This method is called from within SomeMethod()
subject = new SomeClass(dependency);
// Act
subject.SomeMethod("Invalid Input");
}
// Assert
[Test]
public void should_log_an_exception_to_the_logger()
{
// Do stuff to verify that an exception has been logged
}
// More tests
}
As you might expect, the code in SomeMethod() throws an exception (as expected), wich makes every test fail (unwanted). I workaround this by doing
try
{
// Act
subject.SomeMethod("Invalid Input");
}
catch(Exception ex)
{
// Swallow, this exception is expected.
}
But that is just ugly.
What I would like to be able to do is
[SetUp]
[ExpectedException] // <-- this works for Test methods, but not for SetUp methods
public void Setup()
{
// etc...
}
but I can't find anything like it.
Do you know of anything?
I don't think using an attribute like ExpectedException is a good idea.
SetUp is to prepare something for the test methods, it shouldn't throw exception.
If it must throw, and you want to limit the code line number. Then put them into one line like below:
try { subject.SomeMethod("Invalid Input"); }catch { }
It doesn't work in Setup for a reason, not because of NUnit's bug.
It's a very bad practice for a unit-test to have exception throwing inside the SetUp method. If you are testing a particular scenario where a exception is the expected result, it should be done inside a [Test] method. You should rearrange your code subsequently.
Your "act" step should be in the test method not the setup.
The setup is for setting up pre-requisite conditions and common objects for the test(s) - i.e. common or repeated "arrange" steps.
Each test method should "act" and "assert" individually (and may also need additional "arrange" steps specific to the test).

Refactoring code that uses new operator to be more testable

I have the following code and am trying to unit test it:
public override IRenderable GetRenderable()
{
var val = SomeCalculationUsingClassMemberVariables();
return new EquationRenderable(val);
}
It seems like I want to use a factory here so I can separate the creation of the IRenderable from this class. The problem is that I have many of these classes that create different IRenderables that are constructed in different ways, so I would need to implement a new factory method for each one. What is the best way to solve this problem?
Good question.
First of all, feeling tempted to use AbstractFactories everywhere smells a bit as DI container is not used the "right" way or design could be improved.
But sometimes I've also come across this problem. I see following:
using AbstractFactory/Factory and Inject it. For C# you have to advantage that you can pass delegates, acting as interface for the creation of instance.
'new' is OK, simply test the output of 'new'.
Stub the call of 'new' inside extracted method (hacky!!)
Injection got mentioned already so I won't repeat. I am more into Java so please excuse some syntax errors.
Test the output of 'new'
I often use this, if the 'new' created instances are domain-objects and not services. Because it is returned directly in method I can test the direct output with my test.
Prod-Code:
...
public override IRenderable GetRenderable()
{
var val = SomeCalculationUsingClassMemberVariables();
return new EquationRenderable(val);
}
Test Case:
...
[Test]
public void test_new()
{
SUT sut = ...;
IRenderable r = sut.GetRenderable();
assertTrue(r instanceof EquationRenderable);
}
Stub the call of 'new' itself
Testing direct output from above is only possible if you somehow get it as return value. Things get more complicated if the "sideeffect" of your code are indirect outputs, which you can't sense directly by the return value. If so I often extract-method of the new-creation and then have it under control in my test. This is yucky and I more use it to go safe with my test and start more refactoring later (DI and factories). I sometimes do this in legacy code where services are created with 'new' directly and refactoring to DI is too risky without tests.
Prod-Code:
...
public override IRenderable GetRenderable()
{
var val = SomeCalculationUsingClassMemberVariables();
return createEquationRenderable();
}
public IRenderable createEquationRenderable()
{
return new EquationRenderable(val);
}
Test Case:
...
class Stubbed : SUT
{
boolean called = false;
public override EquationRenderable createEquationRenderable()
{
called=true;
return MyMock();
}
}
[Test]
public void test_new()
{
Stubbed sut = new Stubbed();
sut.GetRenderable();
assertTrue(sut.called);
// do further stuff on MyMock
}
I know, the example is overkill and a bit senseless, it is just for describing the idea. I am sure above could be shortcutted with mocking-frameworks for C#. Anyway testing the return-value direct output is more trivial and better approach here.
Maybe you have a more detailed example?
depending on the uniformity of your concrete IRenderable constructors you can use the following pattern for factory creating
public IRenderable CreateInstance<T>(object calculation) where T : IRenderable
{
Activator.CreateInstance<T>(new[] { calculation });
}
or if you have many different constructors you can use the params keyword to pass arbitrary amounts of arguments
public IRenderable CreateInstance<T>(params object[] args) where T : IRenderable
{
Activator.CreateInstance<T>(args);
}
To be able to do some kind of runtime check of the arguments you use this code before calling the Activator.CreateInstance
var types = args.Select(o => o.GetType()).ToArray();
var c = typeof(T).GetConstructor(types);
if (c == null)
{
throw new InvalidOperationException("No matched constructor")
}
A better way may be to simply unit test the code as is instead of refactoring it. Technically, this can be done by using a suitable mocking tool such as TypeMock Isolator or Microsoft Moles (there is a third one which I don't remember now).

Categories

Resources