Am trying to get started using TDD on a class which spits out an object belonging to a third party component. However am getting a bit confused in that apparently:
a) With unit tests objects should be tested in isolation
b) Third-party components should be wrapped into an adapter
Do these rules apply when writing tests for code which returns an instance of an object belonging to a third party component? As an example, here's the test so far:
// Arrange
string foodXml = "<food><ingredient>Cabbages</ingredient>" +
"<ingredient>Bananas</ingredient></food>";
IFoodMixer mixer = new FoodMixer();
// Act
// Smoothie is the third-party component object
Smoothie urgh = mixer.Mix(foodXml);
// Assert
Assert.AreEquals("Cabbages", urgh.Ingredients[0].Name);
Assert.AreEquals("Bananas", urgh.Ingredients[1].Name);
Apologies if this question seems a bit basic (or if the concept above seems a tad silly!) - am just struggling to understand how the two rules above could apply in this situation.
Thanks in advance for any advice given!
I would be practical with it. If Smoothie is just a data object, don't bother wrapping it.
There's something inside that FoodMixer which is creating the Smoothie in the first place. If that's a 3rd party component, I would wrap it up (you can delegate from a class to a static method if required), then dependency-inject the wrapper and mock it out in your unit test.
Your unit test is then describing the behaviour and responsibilities of your FoodMixer, independently of the SmoothieMaker (whether it's 3rd-party or otherwise). Part of the FoodMixer's responsibility is to ask the SmoothieMaker for a Smoothie, not to actually make the Smoothie itself. By mocking it out we can express that responsibility and class scope.
If your Smoothie is not just a data object but has rich behaviour, I would wrap that within your wrapped SmoothieMaker too.
Now you are completely decoupled from your 3rd party libraries, and you can unit-test easily as a useful by-product.
Look at mockito as a simpler way to create mocks automatically and verify assertions instead of using adapters.
There are also many good tutorial on mockito (and JMocks) that are also good TDD tutorials.
Related
I have this large legacy WPF application that has no unit testing being done, and huge amount of dependencies all over the place. I'm trying to use Moq to create unit tests, but it doesn't help me much, when so many (=almost all) classes create dependencies internally, so I have no way to inject my mock objects instead of real references.
In C++ you could just write your own fake classes and make sure they are included before the real ones in the test project --> that way all references throughout the project could be made to refer the fake object, including all internally made references.
Is there no way in .NET to accomplish the same?
Thanks in advance for any advice!
-Seppo
P.S. This is a follow-up on an earlier question NUnit/Moq: I have mocked a class but real contructor is executed, why?.
Microsoft Shims and Fakes should do what you want it to do, but it's only available on Visual Studio Ultimate and Premium.
Beyond MS Fakes/Shims, there isn't anything in C# out of the box (or any free libraries I'm aware of) that would do what you want.
What you can do is use a "partial mock". Say your class A creates an instance of class B internally in a test unfriendly construct, for example a private method.
You can move that new ClassB() to a factory method protected virtual method CreateClassB(...) and then use Moq's CallBase.
So if you are testing ClassA's MethodA
[Test]
public void MethodA_StateThatYouAreTesting_ExpectedResult()
{
var partialMockA = new Mock<ClassA>{CallBase=true};
var stubB = new Mock<ClassB>();
stubB.Setup(b => b.SomeMethod()).Returns(SomeValue);
parialMockA.Setup(a => a.CreateClassB()).Returns(stubB.Object);
var result = partialMock.MethodA();
Assert.AreEqual(someExpectedValue, result);
}
This saves you the extra step of creating an interface for ClassB. I believe this is reasonable in situations where the code you inherited is not well structured, and ClassB should actually be broken down in several classes and corresponding interfaces (i.e., does not follow the single responsibility principle). I like to think of this as a first step in re-factoring.
Also, an alternative to Fakes is TypeMock. Never used it, but since it's from Roy Osherove (the guy that wrote The Art of Unit Testing) it is probably a safe bet.
I am looking for ideas to lead me to implement component testing for my application. Sure I use Unit Testing to test my single methods by utilizing TestMethods in a separate project but at this point I am more interested in testing in a higher level. Say that I have a class for Caching and I wrote unit tests for each and every method. They all contain their own instance of the class. And it works fine when I run the test, it initiates an object from that class and does one thing on it. But this doesnt cover the real life scenario in which the method is called by other methods and so on. I want to be able to test the entire caching component. How should I do it?
It sounds like you are talking about integration testing. Unit testing, as you say, does a great job of testing classes and methods in isolation but itegration testing tests that several components work together as expected.
One way to do this is to pick a top (or high) level object, create it with all of its dependencies as "real" objects as well and test that the public methods all produce the expected result.
In most cases you'll probably have to substitute stubs of the lowest level classes, like DB or file access classes and instrument them for the tests, but most objects would be the real thing.
Of course, like most testing efforts, all this is achieved much easier if your classes have been designed with some sort of dependency injection and paying attention to good design patterns like separation of concern.
All of this can be done using the same unit testing tools you've been using.
I would download the NUNIT-Framework
http://www.nunit.org/
It's free and simple
I'm working on this ,let's call it legacy, code that makes calls to another component using an interface (IFjuk).
I realize that mocking is generally intended for unit testing, but I thought it might be useful for a form of "system test". My primary goal is to get rid of a dependency on a piece of external hardware.
The execution makes many calls to IFjuk, which would make it cumbersome to manually write and maintain code that defines the mock expectations.
One idea I have is to use Castle Dynamic Proxy to record calls (including return values from the real component) and generate C# code from that which defines RhinoMock mocks, but I suspect someone must have built something similar already...
Is there a tool that can record calls and responses to IFjuk against the actual component, so that I can use that data to generate mocks?
No there is no any builtin "call tracer" available, but I think this is one of the place where AOP http://www.c-sharpcorner.com/uploadfile/shivprasadk/aspect-oriented-programming-in-C-Sharp-net-part-i/ can become very useful.
In a .NET windows app, I have a class named EmployeeManager. On instantiation, this class loads employees into a List from the database that haven't completed registration. I'd like to use EmployeeManager in unit test. However, I don't want to involve the database.
From what I understand about this scenario, I need an IEmployeeManager interface, which is only used for testing purposes. This doesn't seem right since the interface has no other use. However, it will allow me to create some EmployeeManager test class that loads employees without involving the database. This way, I can assign values that would have otherwise come from the database.
Is the above correct and do I need to Mock it? Mocking (Moq framework) seems to use lots of code just to do simple things such as assigning a property. I don't get the point. Why mock when I can just create a simple test class from IEmployeeManager that will provide what I need?
Inversion of control is your solution, not Mock objects. Here's why:
You mock the interface to make sure that some code that utilizes your IEmployeeManager is using it properly. You aren't using the test code to prove IEmployeeManager works. So there has to be another class that takes an IEmployeeManager, for instance, which you will actually be testing with your mock object.
If you are actually just testing EmployeeManager, you can do much better. Consider dependency injection. In this manner, you will expose a constructor for EmployeeManager that will take at least one parameter which is an interface. Your EmployeeManager code will internally use this interface for any implementation specific calls that it needs to make.
See Strategy Pattern
This will lead you into a whole, exciting world of Inversion of Control. And as you dig into that, you will find that problems like these have been effectively solved with IoC containers such as AutoFac, Ninject, and Structure Map, to name a few.
Mocking interfaces is great, and you can mock an interface that you then pass into IoC. But you'll find that IoC is a much more robust solution to your problem. And yes, while you might only be implementing a second alternative just for testing, it is still important to do for that very reason -- seperating the strategy under test from the business logic of EmployeeManager.
From what I understand about this scenario, I need an IEmployeeManager interface, which is only used for testing purposes. This doesn't seem right since the interface has no other use.
It's well worth creating the interface. Note also that the interface actually has multiple purposes:
The interface identifies roles or responsibilities provided by an actor. In this case, the interface identifies the roles and responsibilities of the EmployeeManager. By using an interface you're preventing an accidental dependency on something database specific.
The interface reduces coupling. Since your application won't depend on the EmployeeManager, you're free to swap out its implementation without needing to recompile the rest of the application. Of course, this depends on project structure, number of assemblies, etc., but it nevertheless allows this type of reuse.
The interface promotes testability. When you use an interface it becomes much easier to generate dynamic proxies that allow your software to be more easily tested.
The interface forces thought1. Ok, I kind of already alluded to it, but it's worth saying again. Just using an interface alone should make you think about an object's roles and responsibilities. An interface shouldn't be a kitchen sink. An interface represents a cohesive set of roles and responsibilities. If an interface's methods aren't cohesive or aren't almost always used together then it's likely that an object has multiple roles. Though not necessarily bad, it implies that multiple distinct interfaces are better. The larger an interface the harder it is to make it covariant or contravariant and, therefore, more malleable in code.
However, it will allow me to create some EmployeeManager test class that loads employees without involving the database.... I don't get the point. Why mock when I can just create a simple test class from IEmployeeManager that will provide what I need?
As one poster pointed out, it sounds like you're talking about creating a stub test class. Mocking frameworks can be used to create stubs, but one of the most important features about them is that they allow you to test behavior instead of state. Now let's look at some examples. Assume the following:
interface IEmployeeManager {
void AddEmployee(ProspectiveEmployee e);
void RemoveEmployee(Employee e);
}
class HiringOfficer {
private readonly IEmployeeManager manager
public HiringOfficer(IEmployeeManager manager) {
this.manager = manager;
}
public void HireProspect(ProspectiveEmployee e) {
manager.AddEmployee(e);
}
}
When we test the HiringOfficer's HireEmployee behavior, we're interested in validating that he correctly communicated to the employee manager that this perspective employee be added as an employee. You'll often see something like this:
// you have an interface IEmployeeManager and a stub class
// called TestableEmployeeManager that implements IEmployeeManager
// that is pre-populated with test data
[Test]
public void HiringOfficerAddsProspectiveEmployeeToDatabase() {
var manager = new TestableEmployeeManager(); // Arrange
var officer = new HiringOfficer(manager); // BTW: poor example of real-world DI
var prospect = CreateProspect();
Assert.AreEqual(4, manager.EmployeeCount());
officer.HireProspect(prospect); // Act
Assert.AreEqual(5, manager.EmployeeCount()); // Assert
Assert.AreEqual("John", manager.Employees[4].FirstName);
Assert.AreEqual("Doe", manager.Employees[4].LastName);
//...
}
The above test is reasonable... but not good. It's a state-based test. That is, it verifies the behavior by checking the state before and after some action. Sometimes this is the only way to test things; sometimes it's the best way to test something.
But, testing behavior is often better, and this is where mocking frameworks shine:
// using Moq for mocking
[Test]
public void HiringOfficerCommunicatesAdditionOfNewEmployee() {
var mockEmployeeManager = new Mock<EmployeeManager>(); // Arrange
var officer = new HiringOfficer(mockEmployeeManager.Object);
var prospect = CreateProspect();
officer.HireProspect(prospect); // Act
mockEmployeeManager.Verify(m => m.AddEmployee(prospect), Times.Once); // Assert
}
In the above we tested the only thing that really mattered -- that the hiring officer communicated to the employee manager that a new employee needed to be added (once, and only once... though I actually wouldn't bother checking the count in this case). Not only that, I validated that the employee that I asked the hiring officer to hire was added by the employee manager. I've tested the critical behavior. I didn't need even a simple test stub. My test was shorter. The actual behavior was much more evident -- it becomes possible to see the interaction and validate interaction between objects.
It is possible to make your stub test class record interactions, but then you're emulating the mocking frameworks. If you're going to test behavior -- use a mocking framework.
As another poster mentioned, dependency injection (DI) and inversion of control (IoC) are important. My example above isn't a good example of this, but both should be carefully considered and judiciously used. There's a lot of writing on the subject available.
1 - Yes, thinking is still optional, but I'd strongly recommend it ;).
Creating an IEmployeeManager interface in order to be able to mock is that way most .NET developers would go about making such a class testable.
Another option is to inherit from EmployeeManager and override the method you want to test so it will not involve the database - this too means you will need to change your design.
Extracting interface in your scenario is a good idea. I would not worry too much about the fact that you only need this for testing. Extracting this interface makes your code decoupled from database. After that you will have a choice between writing your own implementation for testing or use mocking framework to generate this implementation for you. This is a matter of personal preference. It depends on how familiar you are with mocking framework and whether you want to spend time learning new syntax.
In my opinion it is worth learning. It will save you a lot of typing. They are also flexible and don't always require an interface to generate test implementation. RhinoMocks for example can mock concrete classes as long they have empty constructor and methods are virtual. Another advantage is that mocking APIs use consistent naming so you will get familiar with 'Mocks', 'Stubs' etc. In your scenario by the way you need stub, not mock. Writing an actual mock manually may be more labor intensive than using framework.
The danger with mocking frameworks is that some of them are so powerful and can mock pretty much anything, including private fields (TypeMock). In other words they are too forgiving to design mistakes and allow you to write very coupled code.
This is a good read on the subject of hand written vs. generated stubs
By making your classes implement Interfaces you are not only making them more testable, you're making your application more flexible and maintainable. When you say "This doesn't seem right since the interface has no other use", is flawed since it allows you to loosely couple your classes.
If I could suggest a couple of books Head First Design Patterns and Head First Software Development will do a much better job of explaining the concepts then I could in a SO answer.
If you don't want to use a mocking framework like Moq, it's simple enough to roll your own mock/stubs, here is a quick blog post on it Rolling your own Mock Objects
Consider the following method that stops a service:
Public Function StopService(ByVal serviceName As String, ByVal timeoutMilliseconds As Double) As Boolean
Try
Dim service As New ServiceController(serviceName)
Dim timeout As TimeSpan = TimeSpan.FromMilliseconds(timeoutMilliseconds)
service.[Stop]()
If timeoutMilliseconds <= 0 Then
service.WaitForStatus(ServiceControllerStatus.Stopped)
Else
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout)
End If
Return service.Status = ServiceControllerStatus.Stopped
Catch ex As Win32Exception
'error occured when accessing a system API'
Return False
Catch ex As TimeoutException
Return False
End Try
End Function
In order to unit test the the method I basically have two options:
Use the Adapter pattern to wrap the ServiceController class's methods I need into an interface I can control. This interface can then be injected into the service class (a.k.a Inversion of Control). This way I have a loosely coupled code and can use the traditional mocking frameworks to test.
Keep the class as is and use
Microsoft Moles (or any other code
detouring framework) to intercept
the calls to ServiceController to
return canned results for testing
purposes.
I agree that for domain model code that using the "traditional" unit testing approach makes the most sense as this would lead to a design that is easiest to maintain. However, for code that deals with the .net implementation of Windows API related stuff (file system, services, etc), is there really an advantage to going thru the extra work to get "traditionally" testable code?
It's hard for me to see the disadvantages of using Microsoft Moles for things such as ServiceController (or the File object). I really don't see any advantage of doing the traditional approach in this case. Am I missing anything?
Great question btw.. Just had a look at MS Moles video right now. Although I'm skeptical of MS Unit-testing tools, I must say this one looks interesting. My comparison stands at:
Adapter/Facade
Pro: allows you to extract a meaningful role with intention revealing methods. e.g. ServiceManager.StartService(name) could abstract the details {1. ServiceController.GetServices(), 2. handle case where ServiceController.Status != Stopped, 3. ServiceController.Start()}. The mock/fake approach here would involve less work than setting up 3 delegates. Here this approach is an opportunity to improve your design by coming up with meaningful contracts/interfaces (also allows you to hide stuff that you don't care about -- e.g. Winapi semantics, constants, etc)
Pro: Mocking frameworks would give you better diagnostics for argument checks, number of times called, expectations not called etc.
Interceptor
Pro: Less work if you're just interested in stubbing out a problematic call on a dependency
Pro: definitely a good tool in your toolbox when dealing with legacy code (where the fear of change is overwhelming)
Con: does it have a MSTest dependency? Initial searches seem to indicate that you need some plugins or extensions if you're not using MSTest.
I believe that this is a good case for mocking and there're some advantages of doing it with IoC:
You do actual unit-testing, as your tests aren't testing underlying layers - this would be an integration test -.
Easy to plug and unplug a mock object.
You don't need to define a "fake" implementation on each stub. You've a "fake", mocked implementation by configuration.
For me, the first reason is the most important.
Why don't to use Moles? Because I believe it's not the right tool for something like this. Moles is more for things like I want a fixed value of DateTime.Now to an specific time, so you can test some code in some situation whenever you want with no troubles.
Moles is an easy way to auto-mock certain methods, properties in specific tests, while IoC+fake, it's to isolate your test.