Setting a readonly property of a class for unit testing - c#

I have an interface like this
public interface IConnection
{
Strategy Gc { get; }
bool IsConnected();
bool Connect();
}
I want to unit test methods of a class that uses this interface. Now I want to set Gc but it happens to be readonly. Is there a way to set Gc field without making changes to this interface class?
I am using MS fakes and Nsubstitute for unit testing. However, apparently none provides a solution. PrivateObject does not work either.
Changing Interface is not an option. Suggest better solutions.

With NSubstituteit is quite easy. First create a mock for your interface:
var mock = Substitute.For<IConnection>();
Now you can mock the member by setting any return-type for the property:
mock.Gc.Returns(Substitute.For<Strategy>());
Finally provide that mocked instance as parameter to the service depending on that instance, for example:
var target = new MyClassToTest();
target.DoSomething(mock); // mock is an instance of IConnection
Now whenever your method is called it returns a dumm-instance for Strategy. Of course you can also set any other arbitrary return-type within the Returns-statement. Just have a look at http://nsubstitute.github.io/help/set-return-value for further information.

Related

Are interfaces necessary for mocks in unit test?

I have read that you need to define interfaces in order to mock types but I am not sure how to interpret that.
For example, to mock FileSystem, instead of directly calling some I/O method, I can pass the object to the method and then mock it when calling from my test.
Why are unit test examples (like the one from SO question below), use interfaces?
void DoIt(IZipper zipper, IFileSystem fileSystem, IDllRunner runner)
{
string path = zipper.Unzip(theZipFile);
IFakeFile file = fileSystem.Open(path);
runner.Run(file);
}
Could I not simply use arguments of respective types, and inject the object then?
E.g. in the GUICE guide, they advise to remove constructor work (e.g. no field inicialization with "new" keyword), but use parameters istead.
It depends on your mocking framework. Using Moq, you can mock concrete types as long as they aren't sealed and the members you want to mock are virtual. Interfaces are generally preferred because their members don't need to (and can't) be marked as virtual. (There are other reasons to prefer interfaces such as to keep the coupling between your classes loose)
https://github.com/Moq/moq4/wiki/Quickstart
Update
Generally you will mock an instance of a type. Therefore you can't test static method calls like FileStream.Open because there is no instance to mock.
Update
Frameworks like Moq rely on inheritance to generate the mocks. That's why methods need to be virtual. If you want to mock static or private methods, try Microsoft Fakes.
https://msdn.microsoft.com/en-us/library/hh549175.aspx
It is not must to have interface as dependency but that's recommended and widely followed practice.
Using interface and base classes as dependency helps you creating lossely couple design.
Loosely coupled design makes it possible to create modules/layers of application without depending on the implementation details about other layer.
This also makes it super easy to test the piece of code in isolation without worrying about how other layer would work or react.
This type of testing is called unit testing.
If you have dependency on concrete class then you can't unit test code in isolation. Such tests are prone to fail whenever implementation of dependency changes. If your code is dependent on actual file system class or data access class which connects to actual db then there are chances that the unit tests will fail when file is not accessible or db server is down or data is currupted.
This even won't be called unit testing. It is called integration testing.
As I mentioned, while testing code in isolation you don't need to worry about how the dependency works. That's why, while unit testing the dependencies are mocked. Also dependencies must not be an interface. It can be a base class too. When you mock dependency, mocks do not have actual implementation of any of the functionality. How many ways you can create mocks, is a different topics altogether.
Using mocks, in unit testing, you just need to make sure that they behave per your expectations while you test the code your current class. So you ask the mock to behave the way you want, make sure that certain methods or properties of mock called, so that you can cover all the paths of the piece of code which you are testing.
Following is a simple example of Unit Testing with dependency.
public class ProductService
{
private IProductRepository repository;
public ProductService (IProductRepository repository)
{
this.repository = repository;
}
public Product GetProductById(int productId)
{
if(productId <= 0)
return null;
var product = this.repository.GetProductById(productId);
return product;
}
}
While Creating ProductService class, even if I don't have actual implementation of IProductRepository interface, I can still unit test ProductService class as following.
public class ProductServiceTests
{
ProductService serviceToTest;
IProductRepository productRepository;
public ProductServiceTests()
{
this.productRepository = Mock<IProductRepository>();
this.serviceToTest = new ProductService(productRepository);
}
public void GetProductByIdReturnsNullIfProductIdIsZero()
{
int productid = 0;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsNullIfProductIdIsNegative()
{
int productid = -1;
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Null);
}
public void GetProductByIdReturnsProductIfProductIdIsPositive()
{
var productid = 1;
var product = new Product { Id = productId };
productRepository.Setup(repo => repo.GetProductById(productid)).Returns(product); //Making sure that GetProductById method of repository is called and return an object of product as this call is part of the code which I am testing right now.
var product = serviceToTest.GetProductById(productid);
Assert.That(product, Is.Not.Null);
Assert.That(product.Id, Is.EqualTo<int>(productid));
}
}
This is an example code to illustrate the unit testing. It might not build or run as expected and I apologies for that.
edit
Found an excellent article on mocking classes https://www.wrightfully.com/how-net-mocking-frameworks-work
This should clear doubts of how class mocking is different than the interface mocking.

How to setup property when mocking a concrete class

I am attempting to mock (using Moq) a classes and interfaces that are defined in a third party SDK. Here's a simplified example of what they look like:
public interface IVehicle
{
string Type { get; }
}
public class Vehicle
{
public string Type { get; }
}
public class Jeep : Vehicle, IVehicle
{
}
I can easily mock the interface like so:
var mockVehicle = new Mock<IVehicule>(MockBehavior.Strict);
mockVehicle
.SetupGet(v => v.Type)
.Returns("My custom vehicle");
but I need to write a unit test specific to the Jeep class and I can't figure out how to mock it.
My first attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
yielded the following error:
Moq.MockException: IVehicle.Type invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
which is understandable since I haven't setup the Type property.
My second attempt:
var mockJeep = new Mock<Jeep>(MockBehavior.Strict);
mockJeep
.SetupGet(v => v.Type)
.Returns("Jeep");
yielded the following error message:
System.NotSupportedException: Invalid setup on a non-virtual (overridable in VB) member: v => v.Type
which is also understandable since the Type property on the Vehicle class is not virtual.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The best Moq can do in this case is create a proxy as a derived class of Jeep but it cannot override the non-virtual Type property. Remember that when you attempt to create a Mock with Moq, the framework generates a class that either implements the target interface or derives from the target class.
Microsoft Fakes work well with Moq provided that you have the Visual Studio license level to access it.
Since this is a rather generalized question, I'm going to suggest a different approach. Mocking / Faking / Stubbing a class or interface that you don't control is generally difficult. Furthermore, this typically leads to replicating someone else's functionality in your mock instance.
A better approach is to isolate interaction with the external library into a wrapping class that you control the interface and implementation of. This will allow you to easily mock/fake/stub your interface for testing consumers of your interface.
This still leaves the question of what to do with the isolation layer class. For this, you'll need to do more of an integration test that actually exercises both your wrapping class and the external class. Then, verify that you get the expected behavior from the combination of your class and the external classes you're wrapping.
So my question is: is there a way to setup the Type property when mocking the Jeep class?
The short answer is no, you cannot Mock a non virtual member using Moq.
However, I don't think there's any reason in this case to mock anything, since there isn't any behaviour to mock. The only member you have there is a simple string property. So even if you could, you probably shouldn't.
If you are trying to test the Jeep class, just test it directly
without mocking any of its members; mocking should only be used when you need to control the behaviour of one of the dependencies of the System Under Test (SUT)
If you are passing the Jeep
class to another method as a dependency in order to test that method, you can just
new up a Jeep instance and pass it in your test in this case; since it doesn't
have any boundary-crossing behaviours (network calls, etc) then there
is no need to mock it.
You might also consider that if it's the second case, you ought to be able to pass an IVehicle instead of a Jeep, in which case mocking is back on the table (although as mentioned, there is no apparent need in this case)
Incidentally, your hierarchy looks a little off - why does Vehicle not itself implement IVehicle?
i.e.
public interface IVehicle
{
string Type { get; }
}
public class Vehicle: IVehicle
{
public string Type { get; }
}
public class Jeep : Vehicle
{
}
Then Jeep will already be both a Vehicle and an IVehicle :)
disclaimer: I work at Typemock.
By using Typemock Isolator you will be able to mock non-virtual methods and won't need to change your code in order to do so, in this specific example you can fake an instance of Jeep and then modify his methods behavior.
Here is an example for a test that mock Jeep:
[TestMethod]
public void CallFakeJeepType_WillReturnWantedString()
{
var jeep = Isolate.Fake.Instance<Jeep>();
Isolate.WhenCalled(() => jeep.Type).WillReturn("fake jeep");
var result = Jeep.DoSomthing(jeep);
Assert.AreEqual("fake jeep", result);
}
note: if the Jeep.Type had a setter as well you could use typemock's True property and the test will look like this
var jeep = Isolate.Fake.Instance<Jeep>();
jeep.Type = "fake jeep";

How to unit test a service which uses caching?

I have a service layer, which has a range of methods. These methods have implemented caching, like the following:
string key = "GetCategories";
if (CacheHandler.IsCachingEnabled() && !CacheHandler.ContainsKey(key))
{
var categories = RequestHelper.MakeRequest("get_category_index")["categories"];
var converted = categories.ToObject<List<Category>>();
CacheHandler.InsertToCache(key,converted);
return converted;
}
return CacheHandler.GetCache(key) as List<Category>;
Now, problem is I also want to make a unit test, like the following:
[TestMethod]
public void GetCategories()
{
IContentService contentService = new ContentService();
var resp = contentService.GetCategories();
Assert.IsNotNull(resp,"Should not be null");
}
Problem is, that the HttpContext.Current inside my CacheHandler is null during the unit test (obviously).
What is the easiest way to fix this?
(Please be as specific as possible because I haven't done a lot of unit testing before)
This screams dependency injection. The main problem I see is that you access the CacheHandler statically, so in a unit test, you:
a) cannot test the service without "testing" the CacheHandler as well
b) cannot supply any other CacheHandler to the service, for example a mocked one
If that's possible in your case, I'd either refactor or at least wrap the CacheHandler so that the service accesses an instance of it. In a unit test, you can then supply the service with a "fake" CacheHandler, that would not access HttpContext and also could give you a very fine control over the test itself (e.g. you can test what happens when an item is cached vs. when it isn't in two absolutely independent unit tests)
For the mocking part, I suppose it's easiest to create an interface and then use some automocking/proxy-generation framework designed for testing, for example Rhino Mocks (but there are many more, it just happens that I'm using this one and am very happy with it :)). Another approach (easier for a beginner, but more cumbersome in an actual development) would be simply to design the CacheHandler (or its wrapper) so that you can inherit from it and override the behaviour yourself.
Finally for the injection itself, I have found out a handy "pattern", which takes advantage of C# default method arguments and the standard constructor injection. The service constructor would look like:
public ContentService(ICacheHandler cacheHandler = null)
{
// Suppose I have a field of type ICacheHandler to store the handler
_cacheHandler = cacheHandler ?? new CacheHandler(...);
}
So in the application itself, I can call the constructor without parameters (or let frameworks construct the service, if it's ASP.NET handler, WCF service or some other kind of class) and in unit tests, I can supply whatever is implementing the said interface.
In case of Rhino Mocks, it can look like this:
var mockCacheHandler = MockRepository.GenerateMock<ICacheHandler>();
// Here I can mock/stub methods and properties, set expectations etc...
var sut = new ContentService(mockCacheHandler);
Dependency Injection as recommended in Honza Brestan's answer is certainly a valid solution, and maybe the best solution - especially if you might want to use something other than the ASP.NET Cache in the future.
However I should point out that you can use the ASP.NET Cache without needing an HttpContext. Instead of referencing it as HttpContext.Current.Cache, you can use the static property HttpRuntime.Cache.
This will enable you to use the Cache outside the context of an HTTP request, such as in a unit test or in a background worker thread. In fact I'd generally recommend using HttpRuntime.Cache for data caching in the business tier to avoid taking the dependency on the existence of an HttpContext.
Separate the cache into its own class, working like a proxy.
public interface IContentService
{
Categories GetCategories();
}
public class CachingContentService : IContentService
{
private readonly IContentService _inner;
public CachingContentSerice(IContentService _inner)
{
_inner = inner;
}
public Categories GetCategories()
{
string key = "GetCategories";
if (!CacheHandler.ContainsKey(key))
{
Catogories categories = _inner.GetCategories();
CacheHandler.InsertToCache(key, categories);
}
return CacheHandler.GetCache(key);
}
}
public class ContentSerice : IContentService
{
public Categories GetCategories()
{
return RequestHelper.MakeRequest("get_category_index")["categories"];
}
}
To enable caching, decorate the real ContentService with the cache:
var service = new CachingContentService(new ContentService());
To test the cache, create the CachingContentService with a test double as a constructor parameter. Use the test double to verify the cache: call it once and it should call the service behind. Call it twice and it should not call the service behind.
As a best practice, you only want to test one thing during a test and what you're describing has multiple steps. Therefore, it would be best to construct your test of your "RequestHelper.MakeRequest" and other routines so that they run their tests separately from the caching scenario. Testing them separately will let you know if their are problems in these routines or in the caching. You can integrate them later to test them as a group.
To test the caching separately, you can create a mock object to create the HttpContext with the properties that you need. Here are some previous answers that should help you put this together:
How do I mock the HttpContext in ASP.NET MVC using Moq?
Mock HttpContext.Current in Test Init Method

How should I inspect the object graph created by a factory in a unit test

I have some code similar to the following:
public interface IMyClass
{
MyEnum Value { get; }
IMyItemCollection Items { get; }
}
public class MyConcreteClassFactory : MyClassFactoryBase
{
public override IMyClass Create(MyEnum value)
{
var itemBuilder = new MyRemoteItemBuilder();
var itemCollection = new MyLazyItemCollection(itemBuilder)
return new MyClass(value, itemCollection);
}
}
The 'real' code should only care about the fact that the factory returns an instance of IMyClass - not what the concrete implementation is. Still, I would like to test that the factory class does what it is supposed to - build a concrete object graph.
Should I write some tests that call the create method and inspect the properties of the returned object? This question seems to indicate so, but does that still apply if I need to inspect several layers of classes and properties to verify the object graph created by the factory? Wouldn't that lead to test code such as:
var created = objectUnderTest.Create(MyEnum.A);
var itemBuilder = (created.Items as MyLazyItemCollection).Builder;
Assert.IsInstanceOfType(itemBuilder, typeof(MyRemoteItemBuilder));
I'm not particularly fond of the downcast of created.Items, but as I see it that would be the only way to assert that the factory created the MyLazyItemCollection correctly, since not every IMyItemCollection can be expected to have a builder property... And this is only the second layer of the graph. I might need to dig even further into the dependencies of the MyRemoteItemBuilder to see if they were created correctly:
var service = ((created.Items as MyLazyItemCollection)
.Builder as MyRemoteItemBuilder).Service;
Assert.IsInstanceOfType(service, typeof(MyService));
Should I test my factory in this manner, accepting the unsightly nested downcasts - this is test code, after all - or should I pull the IMyItemCollection construction into another factory and add this as a dependency to my MyConcreteClassFactory (so I could inject it from the test code and assert that the value of created.Items was the instance created by my mocked factory). I expect the latter would quickly lead to an explosion in factory-factories and factory-factory-factories. After all, the user of the MyConcreteClassFactory shouldn't need to be bothered with the fact that she has to supply specific sub factories, should she..?
It is of cause depends on needs, but my answer is NO.
You should never design your tests in a manner "Test implementation (or detail)", that might work really nice at the beginning, but after a while you will be in trouble. Implementation is chaning really fast, with each change you are forced to correct many test cases.
In opposite, you must "Test behaviour". It basically means you abstract of all details (concrete class) and you tests cases testing some valuable scenarios, instead of details.
My options is to create "Test implementation" cases, then I'm doind TDD. But later on they have to be refactored out with "Test behaviour" cases.
This is quite important if you case not only about count of test case, but quality in building real Safety Net.

Mock .NET classes using wrapper classes

I have a class that takes a MethodInfo instance and extracts some information from it, but I would like to mock this class. At the moment it is difficult because it takes a MethodInfo, so my plan was to create a wrapper for the MethodInfo class and implement an interface on it. For example:
public interface IMethodInfo
{
string Name { get; }
}
public class MethodInfoProxy : IMethodInfo
{
private readonly MethodInfo _method;
public MethodInfoProxy(MethodInfo method)
{
_method = method;
}
public string Name { get { return _method.Name; } }
}
public class MyClass
{
public MyClass(IMethodInfo method)
{
...
}
}
Another example would be the File.Exists method. The thought would be to create a IFile.Exists and put it on a FileProxy class that would simply delegate to File.Exists.
As I'm new to the whole unit testing world I would like to know if this would be considered a good approach to take?
You have two options here:
Use a mocking framework like Microsoft Moles or TypeMock Isolator that can mock static and sealed classes. This is great because you don't end up changing your code just to isolate the code under test from its dependencies.
Defining interfaces for behaviours that you want to mock, and then creating a default implementation that wraps a static call, or other difficult-to-test api. This is the approach you've suggested and one that I've used a lot. The key thing, when defining these interfaces is to pass the real/mock implementation of the interface into the test class via some form of dependency injection - usually constructor injection. Some people make the mistake of constructing the object within the class being tested and that makes it impossible to test. A good rule of thumb is that when you see objects being constructed in your business code, then that is a code smell - not always a bad thing, but definitely something to view with suspicion. There's a great video about this stuff: The Clean Code Talks - "Global State and Singletons".
There's a bit of a religious war between those who think testing shouldn't change the code and those that think it should. Dependency injection, which is essential if you are going to mock by creating interfaces, leads to code with high cohesion and loose coupling and an intuitive API. But the other approach isn't precluded from these benefits - it's just not so automatic.
I recommend trying to pull the dependencies out of the class - instead of supplying a MethodInfo (or a proxy), just supply the Name.
When that isn't practical, you can either write proxy classes that use an adapter interface (as you've suggested) or use a black-magic tool like TypeMock or Moles (just kidding about the black magic part: I just don't have any experience with them).
If you plan to use the proxy approach, be sure to take a look at the SystemWrapper library, which already handles about twenty classes from the .NET framwork.
You could create a wrapper around each of the class that you use but it would be extremely expensive. It's better to use a mocking framework such as the moles framework by Microsoft http://research.microsoft.com/en-us/projects/pex/ which can also stub out static methods.
A Mock class (or a fake class) would be a class you make to satisfy dependencies and make your test more deterministic by ruling out problems in your dependencies.
public interface IMethodInfo
{
string Name { get; }
}
Your mock class:
FakeMethodInfo : IMethodInfo
{
string Name {get {return "FakeMethod";}}
}
Now, in your unit test, pass the FakeMethodInfo class where you need an IMethodInfo.
The whole purpose is that you know FakeMethodInfo just returns a string so if something fails, it is not the problem.
Don't know what context MethodInfo has in your program. A better example would be
interface IUser
{
string UserName {get;}
}
If it were implemented in a class you would get the actual username from a data base.
Now, if you make a fake one, and pass it around, you kinda simulate a user logged in without a real user, and you rule out that any problem has to do with `IUser.
See this large answer I posted on why you would use mocking. And an example with Moq.:
Difference between Dependency Injection and Mocking framework (Ninject vs RhinoMock or Moq)
For faster creating of wrapper classes, you can use one of the Scaffold code generator I created.
https://www.nuget.org/packages/Digitrish.WrapperGenerator/
This will generate Interface that you can use to any mocking framework and concrete wrapper class for the real implementation.

Categories