How do I remove dependencies to 3rd party code when unit testing? - c#

I've got some code that performs some legacy 'database' operation and then processes the result. I want to write a unit test that checks the method that calls the legacy code without interacting with the 'database'.
My code looks something like this:
public static bool CallRoutine(LegacySession session, /* routine params*/)
{
try
{
LegacyRoutine routine = session.CreateRoutine(/* routine params */);
routine.Call();
// Process result
}
catch (LegacyException ex)
{
// Perform error handling
}
}
Were this all my code, I would create interfaces that the LegacySession and LegacyRoutine implement and then write unit tests that use mock implementations of those interfaces using MOQ or something similar. The problem is that I don't have access to the code for LegacyRoutine or LegacySession so I can't make them implement an interface.
Any ideas about how I could do this without changing the production code too much?

If you can't access LegacyRoutine (i'm guessing it's in a referenced DLL), why not just create a wrapper for it, then flick on/off different implementations:
public interface ILegacyWrapper
{
ILegacyRoutine CreateRoutine();
// etc etc
}
public interface ILegacyRoutine
{
// put members of LegacyRoutine
}
Know what i mean? Just mock everything out into wrappers/interfaces.
Then you could go:
ILegacyRoutine routine = session.CreateRoutine(/* routine params */)
Where session would be declared as an ILegacyWrapper, but implemented with a mock concrete.
Also, it goes without saying (but i'll say it anyway), you should consider a DI framework to make your life simpler. Otherwise you'll end with IFoo foo = new Foo() (hard-coded injection) all over the place.
StructureMap is my DI poison of choice.
HTH

You could write a thin wrapper over their API for which you did have an interface. Whether that's a practical thing to do or not rather depends on the size of the API.

Search for C# mock concrete types. Sorry, I have to run, but here's a link to the first thing I found that will solve your problem (there may be better solutions, but this looks OK):
http://docs.typemock.com/isolator/##typemock.chm/Documentation/CreatingFakesWithAAA.html
Also, check out Moq, which I've had great success with in the past

I would advise you to use a depedency injection framework. It helps you to make your classes more loosely copuled by breaking out external class dependencies into objects which are injected into your classes. These objects are often represented by an interface, which helps you to use different implementations in production and when testing. That way you won't have to actually call the external database when testing. I can recommend Ninject. It's makes dependency injection a lot easier than doing it manually.

Related

Unit Testing IUnityContainer.Resolve

I have an application that is using Unity for DI but I have run into a bit of a snag while writing my unit tests. In a handful of my business layer methods I have code that is similar to this:
var obj = container.Resolve<ISomeObj>();
This is either standing up an in-memory object that will ultimately be passed off to the database, or it is an in-memory object that will ultimately be passed up to the client. The issue though is that RhinoMocks is (seemingly) unable to mock the container properly so doing something like this:
mockContainer = MockRepository.GenerateMock<IUnityContainer>();
mockContainer.Expect(x => x.Resolve<ISomeObj>())
.Return(mockObj);
Getting an exception here seems to make sense since the container is actually empty, but I am not seeing a straightforward way around the problem. I had considered abstracting the container away with a wrapper to get around this problem but that seems to be a bit overkill.
Any thoughts or suggestions are greatly appreciated!
----EDIT----
Since Yacoub posted his answer I have been doing some reading about the Service Locator (anti) Pattern and while it seems to be generally accepted that it is an anti pattern, I haven't found an answer on what to do with POCOs.
Using my example above it seems like the general answer to my problem is to do something like this:
public class Foo()
{
private ISomeObj someObj;
public Foo(ISomeObj injectObj)
{
someObj = injectObj;
}
}
I suppose that my only complaint with this approach is that it will (potentially) make the constructor "busy" ala:
public class Foo()
{
public Foo(ISomeService injectSvc, ISomeObj injectObj, ISomeObj2 injectObj2, ISomeObj3 injectObj3)
{
...
}
}
Further, unless I am missing something, I would need a way to reinitialize a given instance for reuse. Meaning: if MethodA() and MethodB() both consume ISomeObj, when MethodA() finishes with ISomeObj I would need someway to reinitialize all of the fields in ISomeObj so that MethodB() could do its work.
What is the "best" way to approach this problem?
What you are doing (resolving objects using the container from inside your business layer methods) is called Service Location and is considered an anti-pattern. You might want to consider refactoring to use Constructor Injection. And if you do that then you wouldn't need to use the container in your unit tests.
Having said that, here is what you can do without such refactoring: Don't mock the container. Instead, use a real container, and register the mock instance with the container like this:
container.RegisterInstance<ISomeObj>(mockObj); //mockObj is the mocking object that implements ISomeObj
All resolve operations done for this interface (ISomeObj) will return the same instance.
If you need to be able to obtain a new instance for each resolve operation, you can do the following:
container.RegisterType<ISomeObj>(new InjectionFactory(x => GenerateMock()));
Where GenerateMock is the method that creates the mock object. You can replace this call with the code that create the mock using RhinoMocks.

TDD - Am I doing it correctly?

I have a class that deals with Account stuff. It provides methods to login, reset password and create new accounts so far.
I inject the dependencies through the constructor. I have tests that validates each dependency's reference, if the reference is null it throws an ArgumentNullException.
The Account class exposes each of these dependencies through read only properties, I then have tests that validates if the reference passed on the constructor is the same that the property returns. I do this to make sure the references are being held by the class. (I don't know if this is a good practice too.)
First question: Is this a good practice in TDD? I ask this because this class has 6 dependencies so far, and it gets very repetitive and also the tests get pretty long as I have to mock all the dependencies for each test. What I do is just a copy and paste every time and just change the dependency's reference being tested.
Second question: my account creation method does things like validating the model passed, inserting data in 3 different tables or a forth table if a certain set of values are present and sending an email. What should I test here? I have so far a test that checks if the model validation gets executed, if the Add method of each repository gets called, and in this case, I use the Moq's Callback method of the mocked repository to compare each property being added to the repository against the ones I passed by the model.
Something like:
userRepository
.Setup(r => r.Add(It.IsAny<User>()))
.Callback<User>(u =>
{
Assert.AreEqual(model.Email, u.Email);
Assert.IsNotNull(u.PasswordHash);
//...
})
.Verifiable();
As I said, these tests are getting longer, I think that it doesn't hurt to test anything I can, but I don't know if it's worth it as it it's taking time to write the tests.
The purpose of testing is to find bugs.
Are you really going to have a bug where the property exists but is not initialized to the value from the constructor?
public class NoNotReally {
private IMyDependency1 _myDependency;
public IMyDependency1 MyDependency {get {return _myDependency;}}
public NoNotReally(IMyDependency dependency) {
_myDependency = null; // instead of dependency. Really?
}
}
Also, since you're using TDD, you should write the tests before you write the code, and the code should exist only to make the tests pass. Instead of your unnecessary tests of the properties, write a test that demonstrates that your injected dependency is being used. In order or such a test to pass, the dependency will need to exist, it will need to be of the correct type, and it will need to be used in the particular scenario.
In my example, the dependency will come to exist because it's needed, not because some artificial unit test required it to be there.
You say writing these tests feels repetitive. I say you feel the major benefit of TDD. Which is in fact not writing software with less bugs and not writing better software, because TDD doesn't guarantee either (at least not inherently). TDD forces you to think about design decisions and make design decisions all. The. Time. (And reduce debugging time.) If you feel pain while doing TDD, it's usually because a design decision is coming back to bite you. Then it's time to switch to your refactoring hat and improve the design.
Now in this particular case it's just the design of your tests, but you have to make design decisions for those as well.
As for testing whether properties are set. If I understand you correctly, you exposed those properties just for the sake of testing? In that case I'd advise against that. Assume you have a class with a constructor parameter and have a test that asserts the construtor should throw on null arguments:
public class MyClass
{
public MyClass(MyDependency dependency)
{
if (dependency == null)
{
throw new ArgumentNullException("dependency");
}
}
}
[Test]
public void ConstructorShouldThrowOnNullArgument()
{
Assert.Catch<ArgumentNullException>(() => new MyClass(null));
}
(TestFixture class omitted)
Now when you start to write a test for an actual business method of the class under test, the parts will start to fit together.
[Test]
public void TestSomeBusinessFunctionality()
{
MyDependency mockedDependency;
// setup mock
// mock calls on mockedDependency
MyClass myClass = new MyClass(mockedDependency);
var result = myClass.DoSomethingOrOther();
// assertions on result
// if necessary assertion on calls on mockedDependency
}
At that point, you will have to assign the injected dependency from the constructor to a field so you can use it in the method later. And if you manage to get the test to pass without using the dependency... well, heck, obviously you didn't need it to begin with. Or, maybe, you'll only start to need it for the next test.
About the other point. When it becomes a hassle to test all the reponsibilities of a method or class, TDD is telling you that the method/class is doing to much and would maybe like to be split up into parts that are easy to test. E.g. one class for verification, one for mapping and one for executing the storage calls.
That can very well lead to over-engineering, though! So watch out for that and you'll develop a feeling for when to resist the urge for more indirection. ;)
To test if properties are mapped properly, I'd suggest to use stubs or self-made fake objects which have simple properties. That way you can simply compare the source and target properties and don't have to make lengthy setups like the one you posted.
Normally in unit tests (especially in TDD), you are not going to test every single statement in the class that you are testing. The main purpose of the TDD unit tests is to test the business logic of the class, not the initialization stuff.
In other words, you give scenarios (remember to include edge cases too) as input and check the results, which can either be the final values of the properties and/or the return values of the methods.
The reason you don't want to test every single possible code path in your classes is because should you ever decide to refactor your classes later on, you only need to make minimal changes to your TDD unit tests, as they are supposed to be agnostic to the actual implementation (as much as possible).
Note: There are other types of unit tests, such as code coverage tests, that are meant to test every single code path in your classes. However, I personally find these tests impractical, and certainly not encouraged in TDD.

"Stubbing out" a function for unit tests

I have various methods that I would like to unit test using Visual Studio's built in unit testing capability for C#. Things have been going pretty smoothly, but I've run into a scenario where I want to "stub out" a dependency on a particular function call.
Namely, I have some methods that are in the following format:
public class ClassWithMethodsIWantToUnitTest
{
public void myFcn(object someArg)
{
...
LoggerService.Instance.LogMessage("myMessage");
...
}
}
So basically, I want my unit test to simply verify that the call to "LogMessage" has occurred. I don't want to actually check a log file or anything. I want a way to see if the LoggerService line has been hit and executed.
LoggerService is a singleton, and if possible, I don't want to modify the code just for unit testing.
Based on the format of this problem, it seems to me that it should be possible to somehow take control of the code in my unit test. In other words, is there a way for me to make a fake version of LogMessage such that I can use it for my unit test? I don't want the "real" LogMessage function to be called if possible. I just want to test that the code hit the path that called the function.
Does this make any sense? Is this possible?
It certainly makes sense and is not an unknown problem.
Unfortunately you will probably need to change the code, so that it accepts dependency injection. That is, when testing you should be able to inject a specially crafted test object (a mock) instead of the real thing. In your case it probably means being able to set LoggerService.Instance to a special mock object.
The second thing you need is the fake logger instance that you will test against. You probably want a mock, which is a special object that can be set up to check behaviour of the caller. There are several mock frameworks around and I really recommend that you use one instead of trying to roll your own.
Anders' answer was definitely the "canonical" way of approaching the problem, but in .NET 4.5, there's a second option:
The Fakes framework.
It lets you add a "fakes" assembly to your unit test project that accepts a delegate to perform in place of the actual implementation of a method. Here's an example using File.ReadAllText
[TestMethod]
public void Foo()
{
using (ShimsContext.Create())
{
ShimFile.ReadAllTextString = path => "test 123";
var reverser = new TextReverser();
const string expected = "321 tset";
//Act
var actual = reverser.ReverseSomeTextFromAFile(#"C:\fakefile.txt");
//Assert
Assert.AreEqual(expected, actual);
}
}
What that test method is doing is temporarily (within the scope of the ShimsContext) replacing the implementation of File.ReadAllText with the lambda I provided. In this case, any time ReadAllText is called, it returns the string "test 123".
It's slower than regular DI, but if you're absolutely tied to a specific implementation of a singleton, it could be exactly what you need. Read more about it here.
What Anders said.
Several popular mocking frameworks are Moq and RhinoMocks
And you'd change your code so that the logger dependency was injected to your class:
public class ClassWithMethodsIWantToUnitTest
{
public ClassWithMethodsIWantToUnitTest(ILoggerService logger)
{}
public void myFcn(object someArg)
{
...
logger.LogMessage("myMessage");
...
}
}
Or something similar. A DI framework could inject the logger automatically into the class when it needs it. Esentially a DI framework automatically calls
new ClassWithMethodsIWantToUnitTest(LoggerService.Instance);

How test code with lots of dependencies

I am working on a large codebase with basically no unit test coverage. We are about to start moving toward a more test-driven approach, so I thought I would try to write a unit test for a very simple function I added, basically
class ClassUnderTest {
public void SetNoMatchingImage() {
currentState.State = FSMState.NoMatchingImage;
... // Some more logic
NotifyViews();
}
public ViewStatus GetStatus() {
...
if (currentState.State == FSMState.NoMatchingImage)
return ViewStatus.EmptyScreen;
...
}
...
}
Ok, so test this, I would just like to do:
[Test]
public void TestSetNoMatchingImage() {
ClassUnderTest view = new ClassUnderTest(...);
view.SetNoMatchingImage();
Assert.AreEqual(ViewStatus.EmptyScreen, view.Status);
}
But my problem here is that the ClassUnderTest constructor takes 3 arguments to non-interfaces that cannot be null, so I cannot easily create a ClassUnderTest. I can try to either create instances of these classes or stub them, but the problem is the same for them: each of the contructors take arguments that has to be created. And the problem is the same for... and so on. The result is of course a very large overhead and a lot of code needed even for very simple tests.
Is there a good way of dealing with cases like this to make the test cases easier to write?
You'll have lots of situations like this when you start refactoring a project without tests if it wasn't design with Dependency Injection in mind and the mocking framework you use cannot mock concrete classes (such as NMock).
As Andriys just mentioned, Typemock (and moq too) can mock concrete classes as long as it got virtual members.
Personally, I would extract an interface from each of those three classes and inject the interfaces as part of some refactoring to make the class easy to test. I can't remember if VS has a refactor to extract an interface in 2 clicks, which wouldn't take too long.
I would recommend looking at Typemock Isolator framework. According to Art of Unit Testing book by Roy Osherove, it's your best bet when writing unit tests for legacy code:
...it’s the only one [framework] that allows you to create stubs and mocks of dependencies in production code without needing to refactor it at all, saving valuable time in bringing a component under test.
Cheers!
I'd second the recommendation for Typemock, and the solutions suggested in the other answers. In addition to what's already being said Michael Feathers has written a book dealing with the patterns that you're bumping up against called 'Working Effectively With Legacy Code' -
http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052/ref=sr_1_1?ie=UTF8&qid=1313835584&sr=8-1
There's a PDF extract here - http://www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf

Moq, strict vs loose usage

In the past, I have only used Rhino Mocks, with the typical strict mock. I am now working with Moq on a project and I am wondering about the proper usage.
Let's assume that I have an object Foo with method Bar which calls a Bizz method on object Buzz.
In my test, I want to verify that Bizz is called, therefore I feel there are two possible options:
With a strict mock
var mockBuzz= new Mock<IBuzz>(MockBehavior.Strict);
mockBuzz.Setup(x => x.Bizz()); //test will fail if Bizz method not called
foo.Buzz = mockBuzz
foo.Bar();
mockBuzz.VerifyAll();
With a loose mock
var mockBuzz= new Mock<IBuzz>();
foo.Buzz = mockBuzz
foo.Bar();
mockBuzz.Verify(x => x.Bizz()) //test will fail if Bizz method not called
Is there a standard or normal way of doing this?
I used to use strict mocks when I first starting using mocks in unit tests. This didn't last very long. There are really 2 reasons why I stopped doing this:
The tests become brittle - With strict mocks you are asserting more than one thing, that the setup methods are called, AND that the other methods are not called. When you refactor the code the test often fails, even if what you are trying to test is still true.
The tests are harder to read - You need to have a setup for every method that is called on the mock, even if it's not really related to what you want to test. When someone reads this test it's difficult for them to tell what is important for the test and what is just a side effect of the implementation.
Because of these I would strongly recommend using loose mocks in your unit tests.
I have background in C++/non-.NET development and I've been more into .NET recently so I had certain expectations when I was using Moq for the first time. I was trying to understand WTF was going on with my test and why the code I was testing was throwing a random exception instead of the Mock library telling me which function the code was trying to call. So I discovered I needed to turn on the Strict behaviour, which was perplexing- and then I came across this question which I saw had no ticked answer yet.
The Loose mode, and the fact that it is the default is insane. What on earth is the point of a Mock library that does something completely unpredictable that you haven't explicitly listed it should do?
I completely disagree with the points listed in the other answers in support of Loose mode. There is no good reason to use it and I wouldn't ever want to, ever. When writing a unit test I want to be certain what is going on - if I know a function needs to return a null, I'll make it return that. I want my tests to be brittle (in the ways that matter) so that I can fix them and add to the suite of test code the setup lines which are the explicit information that is describing to me exactly what my software will do.
The question is - is there a standard and normal way of doing this?
Yes - from the point of view of programming in general, i.e. other languages and outside the .NET world, you should use Strict always. Goodness knows why it isn't the default in Moq.
I have a simple convention:
Use strict mocks when the system under test (SUT) is delegating the call to the underlying mocked layer without really modifying or applying any business logic to the arguments passed to itself.
Use loose mocks when the SUT applies business logic to the arguments passed to itself and passes on some derived/modified values to the mocked layer.
For eg:
Lets say we have database provider StudentDAL which has two methods:
Data access interface looks something like below:
public Student GetStudentById(int id);
public IList<Student> GetStudents(int ageFilter, int classId);
The implementation which consumes this DAL looks like below:
public Student FindStudent(int id)
{
//StudentDAL dependency injected
return StudentDAL.GetStudentById(id);
//Use strict mock to test this
}
public IList<Student> GetStudentsForClass(StudentListRequest studentListRequest)
{
//StudentDAL dependency injected
//age filter is derived from the request and then passed on to the underlying layer
int ageFilter = DateTime.Now.Year - studentListRequest.DateOfBirthFilter.Year;
return StudentDAL.GetStudents(ageFilter , studentListRequest.ClassId)
//Use loose mock and use verify api of MOQ to make sure that the age filter is correctly passed on.
}
Me personally, being new to mocking and Moq feel that starting off with Strict mode helps better understand of the innards and what's going on. "Loose" sometimes hides details and pass a test which a moq beginner may fail to see. Once you have your mocking skills down - Loose would probably be a lot more productive - like in this case saving a line with the "Setup" and just using "Verify" instead.

Categories

Resources