Category Archives: Unit Testing
Moq (basics, part 1)
How to perform tests when classes or interfaces cannot be instantiated properly?
Let’s say you want to run a test, which has dependencies to something that is not available. You are programming a chess game. A certain constellation needs to be tested, but to get there you need to play the game for at least 20 minutes. Surely, you cannot afford waiting that long. The game has to start right away at the required constellation. This can only be done by simulating certain conditions like the piece positions. The game is still being programmed. It does not have load/save functionality yet.
Assume there is a class called “PositionOfTheQueen”. We need to override existing code without touching the class source code.
And here comes Moq into play.
With Moq you can instantiate classes or interfaces and change their behaviour externally. Method “GetPosition” would not return a calculated value, but a constant that we injected from a test class.
Reference to Inversion of Control
Wiki Mock object
Moq quickstart
In Visual Studio 2013 go to your “Project” menu. Then click “Manage NuGet Packages” and a new window will open. Enter “Moq” in the “Search Online” text box. There are many Moq packages out there. We select the first one from Daniel Cazzulino. It has more than 1.3 million downloads and seems to have gone through teething troubles a long time ago. Press the “Install” button.
The Moq library will be added to your References automatically. You don’t have to do anything. Have a quick look at your Solution Explorer:
Here is the example source code. It is self-explanatory. I have added several tests to highlight issues.
- Moq uses standard default values for anything that has not been Setup().
- Methods with arguments are only defined when they were part of a Setup(). The argument has to be the same when the method is called. Otherwise the method will return the default value. You can define ranges for valid arguments with the class It.
- You can only moq something when it is public virtual. ((“private” is possible but generally of no use.))
- By using Moq you disregard program code. Classes behave like interfaces.
- SetupProperty() can be used for properties that have setters and getters. Use SetupGet() or SetupSet() where this is not the case.
- Set a setter of a property to see if a specific value will be set later on. Change the string in row t2.SetOnly = “xxx”; lMock.Verify(); to observe the behavior. An exception will be raised to tell that the expected value has not been set during any set operation.
using System; namespace Moq { public interface ITestInterface { string GetValue(); string GetValue2(); } // interface public class TestClass { public virtual string GetValue() { return "Genuine as genuine can be"; } public virtual string GetValue2() { return GetValue(); } public virtual string GetValue3(int x) { return x.ToString(); } public virtual string GetValue4(string x) { return x; } public virtual string SetOrGet { get; set; } public virtual string GetOnly { get { return "Value 6"; } } public virtual string SetOnly { set { } } } // class class Program { static void Main(string[] args) { // unaltered class TestClass t1 = new TestClass(); Console.WriteLine("unaltered class:"); Console.WriteLine("GetValue() == " + t1.GetValue()); Console.WriteLine("GetValue2() == " + t1.GetValue2()); Console.WriteLine("GetValue3(99) == " + t1.GetValue3(99)); // mocked class Mock<TestClass> lMock = new Mock<TestClass>(); lMock.Setup(x => x.GetValue()).Returns("You have been mocked!"); TestClass t2 = lMock.Object; Console.WriteLine("\nMocked class:"); Console.WriteLine("GetValue() == " + t2.GetValue()); Console.WriteLine("GetValue2() == " + t2.GetValue2()); Console.WriteLine("GetValue3(99) == " + t2.GetValue3(99)); lMock.Setup(x => x.GetValue2()).Returns("You have been mocked again!"); lMock.Setup(x => x.GetValue3(99)).Returns("11"); //lMock.Setup(x => x.GetValue2()).Returns(() => "You have been mocked again!"); Console.WriteLine("GetValue2() == " + t2.GetValue2()); Console.WriteLine("GetValue3(99) == " + t2.GetValue3(99)); Console.WriteLine("GetValue3(22) == " + t2.GetValue3(22)); Console.WriteLine("After defining the range 22 to 200:"); lMock.Setup(x => x.GetValue3(It.IsInRange(22, 200, Range.Inclusive))).Returns("in range from 22 to 200"); Console.WriteLine("GetValue3(22) == " + t2.GetValue3(22)); Console.WriteLine("GetValue3(99) == " + t2.GetValue3(99)); lMock.Setup(x => x.GetValue4(It.IsAny<string>())).Returns("no"); Console.WriteLine("GetValue4(\"yes\") == " + t2.GetValue4("yes")); // mocked interface Console.WriteLine("\nMocked interface:"); Mock<ITestInterface> lMock2 = new Mock<ITestInterface>(); lMock2.Setup(x => x.GetValue()).Returns("Fictitious result from the happy hunting ground"); ITestInterface t3 = lMock2.Object; Console.WriteLine("GetValue() == " + t3.GetValue()); Console.WriteLine("GetValue2() == " + t3.GetValue2()); Console.WriteLine("After diverting GetValue2():"); lMock2.Setup(x => x.GetValue2()).Returns(() => t3.GetValue()); Console.WriteLine("GetValue2() == " + t3.GetValue2()); // callbacks Console.WriteLine("\nCallbacks:"); Action lBefore = () => Console.WriteLine("before callback"); Action lAfter = () => Console.WriteLine("after callback"); lMock.Setup(x => x.GetValue()).Returns("return value\n").Callback(lAfter); Console.WriteLine(t2.GetValue()); lMock.Setup(x => x.GetValue()).Callback(lBefore).Returns("return value\n"); Console.WriteLine(t2.GetValue()); lMock.Setup(x => x.GetValue()).Callback(lBefore).Returns("return value\n").Callback(lAfter); Console.WriteLine(t2.GetValue()); // Properties Console.WriteLine("\nProperties:"); lMock.SetupProperty(x => x.SetOrGet, "initial value"); // lMock.SetupProperty(x => x.GetOnly, "initial value"); throws exception, because GetOnly is readonly // instead use: lMock.SetupGet(x => x.GetOnly).Returns("initial value"); lMock.SetupSet(x => x.SetOnly = "xxx").Verifiable(); // expect a value t2.SetOnly = "xxx"; lMock.Verify(); //t2.SetOnly = "yyy"; lMock.Verify(); // exception: expected value does not match if t2.SetOnly was NEVER set to "xxx" t2.SetOrGet = "altered value"; Console.WriteLine("SetOrGet == " + t2.SetOrGet); Console.ReadLine(); } // } // class } // namespace
example output:
unaltered class:
GetValue() == Genuine as genuine can be
GetValue2() == Genuine as genuine can be
GetValue3(99) == 99Mocked class:
GetValue() == You have been mocked!
GetValue2() ==
GetValue3(99) ==
GetValue2() == You have been mocked again!
GetValue3(99) == 11
GetValue3(22) ==
After defining the range 22 to 200:
GetValue3(22) == in range from 22 to 200
GetValue3(99) == in range from 22 to 200
GetValue4(“yes”) == noMocked interface:
GetValue() == Fictitious result from the happy hunting ground
GetValue2() ==
After diverting GetValue2():
GetValue2() == Fictitious result from the happy hunting groundCallbacks:
after callback
return valuebefore callback
return valuebefore callback
after callback
return valueProperties:
SetOrGet == altered value
Inversion of Control and Dependency Injection (advanced, Part 1), Programming Patterns
I finally had some time and spent some hours on Inversion of Control (IoC) and Dependency Injection (DI). When I did the same a few weeks ago I did not understand a lot. I got lost on the concept of inversion. I tried to figure out, what the inversion was. This blocked all and I ended up pretty much blank despite nearly an hour of pumping information into my head. When you get lost then you should do it at least properly and at full steam š Well, I finally understood the headline … and the world started making sense again.
Why the name āInversion of Controlā? (IoC)
An entirely hardcoded class controls the program execution path. All branches are predetermined. By using interfaces you can decouple theses flows, so that at the time of creation the class does not exactly know what instructions to call next.
Letās say you are using events. The class, which is raising an event, hands the control over to another class. The subscribing class is in control of the program flow, not the class that raises the event. The subscribing class can subscribe or unsubscribe. The class, which is providing the event, should not have any active control over subscriptions. Hence it is an inversion of control.
By using IoC classes become more encapsulated. Letās say a perfect class is blind and urgently needs a guide dog. The control can now be taken over by external factors. This inverts the control entirely.
Unit testing uses that mechanism. A container can be used to control classes and change the bindings.
What is a container?
The expression ācontainerā is rarely used in C#. The C++ world calls containers what C# calls collections. We have come across containers in my C++ posts. Follow the link for a quick refresher.
To simplify the matter we can call a UnityContainer a dictionary of objects with some additional methods.
This container performs binding between components. For instance it replaces all specific interface declarations by fully instantiated classes without the need to explicitly call any initialization.
What is dependency?
The structure of a program is: Input, Calculations, Output. The same generally applies to classes. Letās say you want to run an analysis of a text file. That analysis class can only function properly if the required text file does exist. The calculations depend on the input. The same applies to the output, which can only run if the calculation was successful.
The input class calls the calculation class, which in turn calls the output class. As we are discussing inversion, letās decouple the classes and implement events. In this case the output class subscribes to the calculation result event and the calculator subscribes to the input event.
What Dependency Injection? (DI)
“Dependency Injection” is a subset of “Inversion of Control”. IoC is a principle, whereas DI is an actual implementation of the principle.
DI is a software design pattern that allows removing hard-coded dependencies. First of all you do not create objects directly; you just describe how they look like. To accomplish this, the pattern uses interfaces or base classes. As the dependency is not hardcoded, the actual object can vary each time. It just needs to fulfill the inheritable pattern of an interface or base class.
public class Car { } // base class public class Audi : Car { } public class BMW : Car { } public class Exhibition { Car StageObject { set; get; } // assign Audi or BMW as the dependency object of class Exhibition }
Interfaces
What are the benefits of interfaces besides multiple inheritance? Several people can work on different problems simultaneously by using interfaces. One person for instance writes the code for logging to text files and another person writes the code for logging to databases. If both use the same interface definition, then the underlying classes can be easily replaced by each other. Interfaces are like promises to provide predefined class patterns at runtime.
Thus we end up with component separation, which is very useful in unit testing. Interfaces can eliminate unfathomable dependencies if used wisely.
Dependency Injection and Unit Testing
When you run unit tests, then you will need input data. But it could be too complex to run the entire program just to test some methods. You would try to only instantiate the minimum requirements. Think of a syringe and inject the data into the test case to create an acceptable environment. This can be difficult in case the program was not structured well. You need to examine the code to find dependencies.
I will cover some IoC/DI basics today and will follow-up on this after some other posts, which were queuing up in the last weeks:
- Calling Java from C#
- Calling C# from Java
- Implement all Java source code examples of the 15 day series C# to C++
- WPF Datagrid formatting
- Google Authenticator
- create a post index for my blog
Dependency Injection
There are several ways to implement dependencies in a class. The easiest way is to have a field that holds a reference to the dependency, which is probably the worst approach you can have in terms of flexibility.
public class Report1 { private IDataBase _DB = new DataBase(); } Report1 r1 = new Report1(); // dependency DataBase must be figured out by examining the code
You can use methods or properties to tell your classes what dependency objects they should use. The best approach though is via constructors. You can hardly miss parameters when trying to call the constructor. Of course bad constructor overloading can jeopardize this concept.
public class Car { } // base class (instead of an interface) public class Audi : Car { } public class BMW : Car { } public class Exhibition { Car StageObject { set; get; } // assign Audi or BMW as the dependency object of class Exhibition } public class Report2 { public IDataBase DB { get; private set; } public void SetDB(IDataBase xDB) { DB = xDB; } } public class Report3 { public IDataBase DB { get; set; } } public class Report4 { private IDataBase _DB; public Report4(IDataBase xDB) { _DB = xDB; } } DataBase lDB = new DataBase(); Report2 r2 = new Report2(); r2.SetDB(lDB); Report3 r3 = new Report3(); r3.DB = lDB; Report4 r4 = new Report4(lDB);
If the world was just like class Report4, then we could more or less end the post here. Unfortunately dependencies are often not that obvious. They are well hidden and you need to read the code thoroughly to build unit tests.
Dependency Injection goes further and the real take off takes place with Moq, which I will explain in the follow-up post.
The following code example was didactically compiled. You don’t need any further information, it should be self-explanatory. You can download unity by following this link or using NuGet.
using System; using Microsoft.Practices.Unity; public interface IDataBase { void QuerySomething(); } // interface public interface ITextFile { void LoadSomething(); } // interface public interface INetwork { string Text { set; get; } void ReceiveSomething(); } // interface public class Network : INetwork { public void ReceiveSomething() { Console.WriteLine("Receiving TCP data ..."); } public string Text { set; get; } } // class public class DataBase : IDataBase { private string _Dummy = "I am doing something."; public void QuerySomething() { Console.WriteLine(_Dummy); } } // class public class TextFile1 : ITextFile { public void LoadSomething() { Console.WriteLine("TF1: Loading something..."); } } // class public class TextFile2 : ITextFile { public void LoadSomething() { Console.WriteLine("TF2: Loading something..."); } } // class public class TextFile3 : ITextFile { public void LoadSomething() { Console.WriteLine("TF3: Loading something..."); } } // class public class Report5 { public string Text = "#N/A"; private IDataBase _DB; public readonly ITextFile TF; public IDataBase getDB() { return _DB; } public Report5(IDataBase xDB, ITextFile xTextFile) { _DB = xDB; TF = xTextFile; } } // class public class Report6 { public readonly string Text1; public readonly string Text2; private readonly ITextFile _TextFile; public readonly INetwork Network; public Report6(ITextFile xTextFile, INetwork xNetwork, string xText1, string xText2) { _TextFile = xTextFile; Network = xNetwork; Text1 = xText1; Text2 = xText2; } // constructor } // class class Program { static void Main(string[] args) { UnityContainer lContainer = new UnityContainer(); // using Microsoft.Practices.Unity; Report5 r; // insufficient data Console.WriteLine("test: insufficient data"); Console.WriteLine("Registering IDataBase"); lContainer.RegisterType(typeof(IDataBase), typeof(DataBase)); // whenever someone asks for an IDataBase, then return a new DataBase instance try { r = lContainer.Resolve<Report5>(); // throws an exception, because ITextFile is undefined } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.WriteLine(); // full data Console.WriteLine("test: sufficient data"); Console.WriteLine("Registering ITextFile TF1"); Console.WriteLine("IDataBase is still registered"); lContainer.RegisterType(typeof(ITextFile), typeof(TextFile1)); r = lContainer.Resolve<Report5>(); Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile1 r.getDB().QuerySomething(); r.TF.LoadSomething(); // this is TextFile1 Console.WriteLine(); // override a previous type registration with another type Console.WriteLine("test: override a previous type registration with another type"); Console.WriteLine("Registering ITextFile TF2"); lContainer.RegisterType(typeof(ITextFile), typeof(TextFile2)); // override the first type registration //lContainer.RegisterType<ITextFile, TextFile2>(); // same as lContainer.RegisterType(typeof(ITextFile), typeof(TextFile2)); r = lContainer.Resolve<Report5>(); Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile2 r.getDB().QuerySomething(); r.TF.LoadSomething(); // this is TextFile2 Console.WriteLine(); // override a previous type registration with an instance Console.WriteLine("test: override a previous type registration with an instance"); Console.WriteLine("Registering an instance of TextFile3"); ITextFile lTextFile = new TextFile3(); lContainer.RegisterInstance(lTextFile); r = lContainer.Resolve<Report5>(); Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile3 r.getDB().QuerySomething(); r.TF.LoadSomething(); // this is TextFile3 Console.WriteLine(); // using names to register instances Console.WriteLine("test: using names to register instances"); lContainer.RegisterType<Report5, Report5>(); // creates a default class without any name Report5 a = new Report5(r.getDB(), r.TF); lContainer.RegisterInstance("A", a); a.Text = "Report A"; Report5 b = new Report5(r.getDB(), r.TF); lContainer.RegisterInstance("B", b); b.Text = "Report B"; r = lContainer.Resolve<Report5>("A"); Console.WriteLine("got " + r.Text); r = lContainer.Resolve<Report5>("B"); Console.WriteLine("got " + r.Text); r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); r.Text = "same instance?"; r = lContainer.Resolve<Report5>("X"); Console.WriteLine("got " + r.Text); // new instance r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); // new instance Console.WriteLine(); // => HAVE A LOOK AT THE BELOW CONTAINER SNAPSHOT => there are 3 instances for Report5 // using names to register instances Console.WriteLine("test: revision, using the same instance"); Console.WriteLine("ContainerControlledLifetimeManager: re-use instances (singleton behaviour for objects)"); lContainer.RegisterType<Report5, Report5>(new ContainerControlledLifetimeManager()); r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); r.Text = "same instance?"; r = lContainer.Resolve<Report5>("X"); Console.WriteLine("got " + r.Text); // new instance r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); // same instance !!!!! Console.WriteLine(); // constructors with parameters lContainer.RegisterType<INetwork, Network>(); lContainer.RegisterType<ITextFile, TextFile2>(); Console.WriteLine("test: constructors with parameters"); ResolverOverride[] lParameters = new ResolverOverride[] { new ParameterOverride("xText1", "Hello "), new ParameterOverride("xText2", "world") }; Report6 lReport6 = lContainer.Resolve<Report6>(lParameters); Console.WriteLine("Report6 text field values are: " + lReport6.Text1 + lReport6.Text2); Console.ReadLine(); } // } // class
example output:
test: insufficient data
Registering IDataBase
Resolution of the dependency failed, type = “Report5”, name = “(none)”.
Exception occurred while: while resolving.
Exception is: InvalidOperationException – The type ITextFile does not have an ac
cessible constructor.
———————————————–
At the time of the exception, the container was:
Resolving Report5,(none)
Resolving parameter “xTextFile” of constructor Report5(IDataBase xDB, ITextFil
e xTextFile)
Resolving ITextFile,(none)
test: sufficient data
Registering ITextFile TF1
IDataBase is still registered
type of r.TF is TextFile1
I am doing something.
TF1: Loading something…
test: override a previous type registration with another type
Registering ITextFile TF2
type of r.TF is TextFile2
I am doing something.
TF2: Loading something…
test: override a previous type registration with an instance
Registering an instance of TextFile3
type of r.TF is TextFile3
I am doing something.
TF3: Loading something…
test: using names to register instances
got Report A
got Report B
got #N/A
got #N/A
got #N/A
test: revision, using the same instance
ContainerControlledLifetimeManager: re-use instances (singleton behaviour for ob
jects)
got #N/A
got #N/A
got same instance?
test: constructors with parameters
Report6 text field values are: Hello world