How to unit test a method with a `using` statement? - c#

How can I write a unit test for a method that has a using statement?
For example let assume that I have a method Foo.
public bool Foo()
{
using (IMyDisposableClass client = new MyDisposableClass())
{
return client.SomeOtherMethod();
}
}
How can I test something like the code above?
Sometimes I choose not to use using statement and Dispose() an object manually. I hope that someone will show me a trick I can use.

If you construct the IMyDisposableClass using a factory (injected into the parent class) rather than using the new keyword, you can mock the IMyDisposable and do a verify on the dispose method call.
public bool Foo()
{
using (IMyDisposableClass client = _myDisposableClassFactory.Create())
{
return client.SomeOtherMethod();
}
}

If you already have your code and are asking how to test it, then you're not writing your tests first...so aren't really doing TDD.
However, what you have here is a dependency. So the TDD approach would be to use Dependency Injection. This can be made easier using an IoC container like Unity.
When doing TDD "properly", your thought processes should run as follows in this sort of scenario:
I need to do a Foo
For this I will rely on an external dependency that will implement an interface (new or pre-existing) of IMyDisposableClass
Therefore I will inject an IMyDisposableClass into the class in which Foo is declared via its constructor
Then you would write one (or more) tests that fail, and only then would you be at the point where you were writing the Foo function body, and determine whether you needed to use a using block.
In reality you might well know that yes, you will use a using block. But part of the point of TDD is that you don't need to worry about that until you've proven (via tests) that you do need to use an object that requires this.
Once you've determined that you need to use a using block you would then want to write a test that fails - for example using something like Rhino Mocks to set an expectation that Dispose will get called on a mock object that implements IMyDisposableClass.
For example (using Rhino Mocks to mock IMyDisposableClass).
[TestFixture]
public class When_calling_Foo
{
[Test]
public void Should_call_Dispose()
{
IMyDisposableClass disposable = MockRepository
.GenerateMock<IMyDisposableClass>();
Stuff stuff = new Stuff(disposable);
stuff.Foo();
disposable.AssertWasCalled(x => x.Dispose());
}
}
Class in which your Foo function exists, with IMyDisposableClass injected as a dependency:
public class Stuff
{
private readonly IMyDisposableClass _client;
public Stuff(IMyDisposableClass client)
{
_client = client;
}
public bool Foo()
{
using (_client)
{
return _client.SomeOtherMethod();
}
}
}
And the interface IMyDisposableClass
public interface IMyDisposableClass : IDisposable
{
bool SomeOtherMethod();
}

Your question doesn't make sense. If you are using TDD, then you should already have a test for what you have written. Requirements, then tests, then design, then development. Either your code passes your tests, or it doesn't.
Now, if your question is how to unit test the above piece of code, then that's another question completely, and I think the other posters have answered it up there.
Sometimes I think there are more buzzwords than developers :)

Wrapper methods like that aren't unit-testable, because you can't specify the relevant preconditions or post-conditions.
To make the method testable, you'll have to pass an IMyDisposableClass instance into the method or into the class hosting Foo (and make the host class itself implement IDisposable), so you can use a test double instead of the real thing to verify any interactions with it.

Your question doesn't make sense. If you are doing TDD, then the method that you posted is already fully tested, otherwise it couldn't even exist in the first place. So, your question doesn't make sense.
If, on the other hand, the method that you posted does already exist, but isn't fully tested, then you aren't doing TDD anyway, and your question about TDD doesn't make sense, either.
In TDD, it is simply impossible for untested code to exist. Period.

You could also change the method signature to allow passing in a mock for unit testing. This would provide an alternative to using a factory, which would also need to be unit tested. DI into the method as opposed to the class constructor may be preferable here.
public bool Foo(IMyDisposableClass mock = null)
{
using (IMyDisposableClass client = mock ?? new MyDisposableClass())
{
return client.SomeOtherMethod();
}
}

If you are testing Foo, then you should be looking at the output of Foo, not worrying about the disposal of the class it is using internally.
If you want to test MyDisposableClass' dispose method to see if it is working, that should be a separate unit test built against MyDisposableClass.
You don't need to unit test the using { } block, since that is part of the language. You either trust that it's working, or don't use C#. :) I don't see the need to write a unit test to verify that Dispose() is being called.

Without a specification for Foo, how can we say how to test it?
Get the specification for Foo.
Write tests to ensure that it meets all specifications and requirements (or a reasonable subset- some functions could require practically infinite amounts of data to test).
I believe you have a second, implicit question in there - which is how to test that use of your MyDisposableClass correctly Disposes of the object when it is freed by exiting an using clause. This is a separate test issue, and shouldn't be combined with the test of Foo, since the specification of Foo shouldn't reference implementation specific details such as the use of your MyDisposabeClass.
I think the other posters have answered this question, so I won't further elaborate.

Related

c# - How to Mock SystemClock.Instance.GetCurrentInstant()? [duplicate]

I am pretty new to use moq. I am into creating some unit test case to HttpModule and everything works fine until I hit a static property as follows
this.applicationPath = (HttpRuntime.AppDomainAppVirtualPath.Length > 1) ? HttpRuntime.AppDomainAppVirtualPath : String.Empty;
I do not know how create mocks for static class and property like HttpRuntime.AppDomainAppVirtualPath. The context, request and response have been mocked well with sample code I get from moq. I will appreciate if somebody can help me on this.
Moq can't fake static members.
As a solution you can create a wrapper class (Adapter Pattern) holding the static property and fake its members.
For example:
public class HttpRuntimeWrapper
{
public virtual string AppDomainAppVirtualPath
{
get
{
return HttpRuntime.AppDomainAppVirtualPath;
}
}
}
In the production code you can access this class instead of HttpRuntime and fake this property:
[Test]
public void AppDomainAppVirtualPathTest()
{
var mock = new Moq.Mock<HttpRuntimeWrapper>();
mock.Setup(fake => fake.AppDomainAppVirtualPath).Returns("FakedPath");
Assert.AreEqual("FakedPath", mock.Object.AppDomainAppVirtualPath);
}
Another solution is to use Isolation framework (as Typemock Isolator) in which you can fake static classes and members.
For example:
Isolate.WhenCalled(() => HttpRuntime.AppDomainAppVirtualPath)
.WillReturn("FakedPath");
Disclaimer - I work at Typemock
You cannot Moq static methods with Moq.
This is not a bad thing in reality, static methods and classes do have their place but for logic they make unit testing difficult. Naturally you'll run into them when using other libraries. To get around this you'll need to write an adapter (wrapper) around the static code, and provide an interface. For example:
// Your static class - hard to mock
class StaticClass
{
public static int ReturnOne()
{
return 1;
}
}
// Interface that you'll use for a wrapper
interface IStatic
{
int ReturnOne();
}
Note, I've ommited the concrete class that uses IStatic for the production code. All
it would be is a class which uses IStatic and your production code would make use of this class, rather than StaticClass above.
Then with Moq:
var staticMock = new Mock<IStatic>();
staticMock.Setup(s => s.ReturnOne()).Returns(2);
As mentioned in previous answers, you can't use MoQ on static methods, and if you need to, your best shot is to create a wrapper around the static class.
However, something I've discovered recently is the Moles project. From the homepage; "Moles allows to replace any .NET method with a delegate. Moles supports static or non-virtual methods." It might be useful for your current situation.
Best solution I have found so far is Telerik's JustMock - unfortunately only the paid for version allows mocking of statics.
While the idea of wrapping statics is a good one - you can't always do this. If you want to test some code that uses some static classes already then it's not always possible to switch out and use a wrapper. In this case JustMock looks a reasonable solution and I'm probably going to use it on some solutions in the near future.
You can use Microsoft Fakes for this. It will definitely solve the issue.
Refer to https://msdn.microsoft.com/en-us/library/hh549175.aspx
Using Microsoft Fakes as suggested by #Sujith is a viable solution. Here is how you actually do it:
Find System.Web in your reference of your test project and right click
Choose "Add". This adds reference System.Web.4.0.0.0.Fakes
Use following code:
using (Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create())
{
System.Web.Fakes.ShimHttpRuntime.AppDomainAppVirtualPathGet = () => "/";
// Do what ever needs the faked AppDomainAppVirtualPath
}

Nsubstitute testing if a private class's method was called

Don't have much experience with testing, trying to change that by testing libraries I've made recently.
Using nunit with nsubstitute for this.
So the situation I have is a class like this:
class MyClassToTest {
private ISomeOtherClass MyPrivateClass { get;set }
public MyClassToTest() {
MyPrivateClass = new SomeOtherClass();
}
public void DoSomething() {
MyPrivateClass.SayHello();
}
}
Now, a test for the DoSomething method would be to see if the method SayHello() was actually called on the ISomeOtherClass instance.
The problem is that it's private, when looking up the best way to test this, the only thing that came up was to make the property internal and set the InternalsVisibleToAttribute to the assembly the tests are in.
While this solution works and the external interface for my library is still ok, the correct accessor for this property in the context of the library would still be private.
The test I'd write is after making it interal:
public void MyTest() {
var objPrivateClass = Substitute.For<ISomeOtherClass>();
var obj = new MyClassToTest();
obj.MyPrivateClass = objPrivateClass;
obj.DoSomething();
objPrivateClass.Received().SayHello();
}
Is there a better way to test this without me having to modify my original code to make it testable?
It might be setting InternalsVisibleToAttribute and making the property internal is the correct thing here, but a couple of hours ago I didn't know about the existence of InternalsVisibleToAttribute so thought it best to ask :)
To answer the exact question, You can use reflection to reach private members, but that is a fragile and rather slow solution.
The best advice I can give you is that private things should stay private; test an object's behavior through its public interface. So if is too big and hard to test, just refactor it to be testable. Think of the Single Responsibility Principle and the Inversion of Control principles.
Edit 1.: You are probably looking for the concept of Dependency Injection. This should be alright most of the times; however when we talk about highly reusable libraries (you mentioned you are making a lib), other solutions may fit better for the users of your library (e.g. creating a Facade or rethinking your design).

How to skip over a method call inside that is inside the method being unit tested

I have a method call that I am unit testing. Inside that method call it makes a call to a method that is going to throw an error because it is trying to talk to a device that will not be available when the unit test is running. Is there a way to avoid that internal method call from being called?
Environment: C# Visual Studio 2010 unit testing within IDE
If you're unit testing a class with external dependencies then you must isolate the external dependancies using an interface which is injected in.
interface IDevice
{
void Run();
}
interface IDeviceOperator
{
void Operate();
}
class DeviceOperator : IDeviceOperator
{
private readonly IDevice _device;
public DeviceOperator(IDevice device)
{
_device = device;
}
public void Operate()
{
_device.Run();
// test other stuff here
}
}
[TestFixture]
public class DeviceOperatorTests
{
[Test]
public void Test_DeviceOperator_Operate()
{
IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax
DeviceOperator deviceOperator = new DeviceOperator(device);
deviceOperator.Operate();
}
}
When doing unit testing you have to create mocks or stubs for all your external dependencies. A framework that could help you with that is Moq (it is plenty of mock frameworks if you want to explore).
These mock or stubs are just facades providing necessary interactions and data to pass your tests.
We may be able to help you more if you provide more details about that unavailable device.
There's probably a better way, but once or twice I've been in this situation where a method calls another, complicated method, and put an optional parameter at the end of the method you're testing like
public void DoSomething(int number, bool skipMethod= false)
{
if(!skipMethod)
MethodThatWillBreak();
{
So that in the normal course of running, it'll be fine, but in your unit test you can do
DoSomething(2,true);
But really, it suggests that you need to do some refactoring of your code, because your unit test should only be hitting one "unit". If you can test the method without calling the MethodThatWillBreak then what is it doing there in the first place.
Check out Working Effectively with Legacy Code book by Michael Feathers - it have a lot of suggestions on dealing with code that does not have unit test yet.
Possible approaches covered in the book:
extract dependency in interface - ideal approach (see jamespconnor's answer)
use flag to bypass call (see Colm Prunty's answer)
extract that call into virtual method and override in derived class used in unit test
pass delegate (may be less impact than full interface/derivation)
Sample for deriving from the class:
public class WithComplexDependency
{
public void DoSomething()
{
// Extract original code into a virtual protected method
// dependency.MethodThatWillBreak();
CallMethodThatWillBreak();
}
virtual protected void CallMethodThatWillBreak()
{
dependency.MethodThatWillBreak();
}
}
in test code derive from the class and provide own implementation:
public class WithMockComplexDependency : WithComplexDependency
{
// may also need to add constructor to call original one.
override protected void CallMethodThatWillBreak()
{
// do whatever is needed for your test
}
}
...
WithComplexDependency testObject = new WithMockComplexDependency();
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak()
...
To unit test correctly you should decouple the comunication with the device from the class you want to test! Abstract the partetalking to the device in another class implementing an interface, inject the communication class in the ctor of the object under test, now you can inject a mock implementation from outside and avoid the errore,the mmock implementation can also log call made to it or respond in a predefined way easing test.
Read a out dependency injection and inversion of control
Typically you would extract external dependencies from the class you're testing and will swap them with fake ones in your unit test. You would isolate them and test the part that you're interested in. I recommend that you look into Inversion of Control as well as one of the many Mocking Frameworks (Moq, Rhino Mocks etc.)
You probably don't want to SKIP the external. Instead you want to isolate the external dependencies such as accessing external devices. There are many ways to do this
a. You can use a third part isolation framework such as Moq, or RhinoMock, etc
b. You can use Moles framework (since you are using VS2010) - replace a .NET method with a delegate
http://research.microsoft.com/en-us/projects/moles/
c. Paid isolation frameworks such as TypeMock.
d. Or simply hand written fake implementation which uses in interface and your test uses the Fake implementation.

Relevant tests for The Service Locator Pattern In C#

I've used this Service Locator Pattern in my Application and implemented as a Singleton:
Service Locator Pattern
And now I want test it .So far I've written a test verifying that my class is a Singleton. I've also written this test:
[Test]
[ExpectedException(typeof(ApplicationException))]
public void GetService_Throws_Exception_When_Invalid_Key_Is_Provided()
{
locator.GetService<IRandomService>();
}
But I don't really like the last test since I'm never going to use the IRandomService. So I'm looking for a nicer way to test that the GetService<T> throws an exception. Also I like to know if there is any other relevants tests I could write for this class.
I'm using the latest version of NUnit.
Cheers
Some things:
A test to verify the class is a singleton? The singleton pattern will ensure that attempting to treat a singleton as an instance class won't even compile. If you have not written your service locator something like the following, it's wrong:
The Singleton Pattern in C#:
public class MySingleton()
{
//Could also be a readonly field, or private with a GetInstance method
public static MySingleton Instance {get; private set;}
static MySingleton()
{
Instance = new MySingleton();
}
private MySingleton() { ... }
}
...
//in external code
var mySingletonInstanceRef = MySingleTon.Instance; //right
var mySingletonInstanceRef = new MySingleton(); //does not compile
//EDIT: The thread-safe lazy-loaded singleton
public class MySingleton()
{
//static fields with initializers are initialized on first reference, so this behaves lazily
public static readonly MySingleton instance = new MySingleton();
//instead of the below you could make the field public, or have a GetInstance() method
public static MySingleton Instance {get{return instance;}
private MySingleton() { ... }
}
The service locator is an anti-pattern. It sounds great, but it doesn't really solve the problems that it was created to solve. The chief problem is that it tightly couples you to the service locator; if the locator changes, every class that uses it changes. By contrast, Dependency Injection can be done without a fancy framework; you just make sure any complex, expensive, reusable, etc. object is passed in to the object that needs it via its constructor. DI/IoC frameworks just streamline this process by ensuring that all known dependencies of a required object are provided, even if an object in the graph can't know about dependencies of its children.
You have already developed the class. The spirit of TDD/BDD is that you write tests that will prove that code you haven't yet written will be correct. I'm not saying writing tests now wouldn't serve a purpose, but a failing test requires the object be opened up and fixed, and if the code is already integrated you could break other things.
Unit tests make heavy use of constructs that will never see production. Mocks, stubs, proxies and other "test helpers" exist to isolate the object under test from the environment into which it is normally integrated, guaranteeing that if the inputs are A, B, and C, the object under test will do X, regardless of whether what it normally hooks into will give it A, B, and C. Therefore, don't worry about creating simple constructs like a skeleton interface that you wouldn't use in production; as long as it is a good representation of the input you would expect in the test case, it's fine.
But I don't really like the last test since I'm never going to use the IRandomService.
But that's kind of the point. You wire up your locator in the test setup method (arrange), and then you lookup a key that was not wired up (act), then you check that an exception was thrown (assert). You don't need to use types you're actually going to use, you just want to get some confidence that your method is working.
Also I like to know if there is any other relevants tests I could write for this class.
Well, I'm going to answer a different question here.
Is the service locator pattern evil?
Yes, it is pure evil.
It defeats the purpose of dependency injection because it doesn't make dependencies explicit (any class can pull anything out of the service locator). Moreover, it makes your all of your components dependent on this one class.
It makes maintenance an unbelievable nightmare because now you have this one component that is just spread all over your codebase. You have become tightly coupled to this one class.
Further, testing is a nightmare. Let's say you have
public class Foo {
public Foo() { // }
public string Bar() { // }
}
and you want to test Foo.Bar.
public void BarDoesSomething() {
var foo = new Foo();
Assert.Equal("Something", foo.Bar());
}
and you run your test and you get an exception
ServiceLocator could not resolve component Frob.
What? Oh that's because your constructor looks like this:
public Foo() {
this.frob = ServiceLocator.GetService<Frob>();
}
And on and on.
avoid, Avoid, AVOID.
I don't quite understand your question. Are you dissatisfied with requesting a type that you'll never use in production? Are you dissatisfied with using the service locator in a fashion that is not indicative of production code? The test itself looks ok to me -- you're requesting something that doesn't exist and proving that the expected behaviour occurs. For a unit test, such a thing is perfectly reasonable to do.
One thing we did when using a dependency injection container was to separate our application wiring phase into modules, then we'd try and resolve the root type in an integration test to ensure that the app could be wired up. If the wiring test failed, it was a good sign that the app wasn't working (though it didn't prove that the app worked, either). It'd be tricker to do this sort of thing when using a service locator.
I agree 100% with Jason, too -- service locators seem like a good idea, but quickly turn nasty. They 'pull' (types using the service locator instance must be coupled to it), whereas Dependency Injection containers 'push' (the vast majority of the application is DI agnostic, so the code is far less brittle and more re-usable).
A couple of other things:
[ExpectedException] is deprecated.
use Assert.Throws
instead
ApplicationException is
also deprecated.

mock object for unit testing rather more related to OOP question

My application has the following project structure: There is the Business Logic project and the UnitTesting project where the methods from the Business Logic are tested. No mocking or testing framework are used (we rely on Visual Studio unit tests and we implement our own mock objects).
In the Business Logic let's say I have the following method:
public static void SomeMethod ()
{
....
if (cond1)
if (cond2)
SendMail();
}
I want to unit test that. I don't want to unit test the sending of the mail, rather the mail is sent under the correct circumstances. So I was thinking to do something like
public class MailSender : ISmtpMail
{
// stuff
}
public class FakeMailSender : ISmtpMail
{
//
static bool SendMail ()
{
return true;
}
}
The problem is that I don't know how to enforce the usage of the FakeMailSender in the unit test project or in the unit test methods which look something like :
[TestMethod]
public static void SomeMethod_Test()
{
// some mock initialization
BusinessLogic.SomeMEthod ();
// checks
}
without changing the BusinessLogic method signature or injecting code (which is undesired)
It's not clear where your first method "lives". It seems to me that:
Your SendMail method shouldn't be static, which makes all kinds of test double injection tricky to say the least
You should inject ISmtpMail into whatever needs to send mail.
You say you want to do it "without injecting code" - why not? The "mail sending" service is clearly a dependency: your code will be clearer, less tightly coupled, and easier to test if you inject that depedency, whether explictly or with the help of a DI container.
The problem is that you're using static methods. There's no clean way of configuring that singleton instance to use different services.
Consider this. Make your SomeMethod non-static and inject the required services into the business logic instance:
private ISmtpMail _smtpMail;
public BusinessLogic(ISmtpMail smtpMail)
{
_smtpMail = smtpMail;
}
public void SomeMethod()
{
...
_smtpMail.Send();
}
Your test code will then be able to enforce which service to use:
[TestMethod]
public static void SomeMethod_Test()
{
// some mock initialization
var bl = new BusinessLogic(new FakeMailSender());
bl.SomeMethod();
// checks
}
For production code, I strongly encourage you to look at some of the excellent Dependency Injection frameworks out there, e.g. Autofac, which makes the service injections happen more or less by magic.
With statics you can use commercial library like Typemock. However, if you are forced to use that it means you have a bad design, probably even misunderstanding the concept of oop. I'd recommend to refactor and use the injection as Jon Skeet and Peter Lillevold already suggested.
First of all you should avoid using any static mocking, and use classical injection pattern as already suggested.
But if you really want to mock static methods (for example, in cases when you can't change this code because this code reside in third-party library), you can use Moles.
Suppose you have following MailSender class:
namespace MyNamespace {
class MailSender
{
public static bool SendMail() {...}
}
}
Moles can generate "mole" for this class with Action delegate witch would be called instead of original method every time your code calls this original method. And than you could write following test:
[TestMethod]
public static void SomeMethod_Test()
{
// After that all calls to MyNamespace.MailSender.SendMail whould
// return true
MyNamespace.Moles.MMailSender.SendMail = () => true;
BusinessLogicClass.SomeMethod();
}
BTW, Moles can also help you mocking not only static methods and non-virtual methods with moles, but this tool can generate similar stub classes for testing interfaces or classes with virtual methods.

Categories

Resources