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.
Related
I'm working on a project that uses Unity Dependancy injection but the load performance is slowly getting worse. I am trying to adjust the code to utilise Lazy<T> (or Func<T>) so i'm trying to find a way to either register the classes with the container using Lazy<T> (or Func<T>) or have some sort of factory that could either adjust the registered types or the constructor but i am not able to seem to find a possible way to do this
At present i have numerous service classes like
public Service1(IClassLogic<GetReq, GetRes> getClass, IClassLogic<AddReq, AddRes> addClass, IClassLogic<UpdateReq, UpdateRes> updateClass, IClassLogic<DeleteReq, DeleteRes> deleteClass....){...}
then i have registrations similar to
container.RegisterType<IClassLogic<GetReq, GetRes>, GetClass>();
container.RegisterType<IClassLogic<AddReq, AddRes>, AddClass>();
container.RegisterType<IClassLogic<UpdateReq, UpdateRes>, UpdateClass>();
container.RegisterType<IClassLogic<DeleteReq, DeleteRes>, DeleteClass>();
...
Ideally i would like not to have to go an change all the signatures to
public Service1(Lazy<IClassLogic<GetReq, GetRes>> getClass, Lazy<IClassLogic<AddReq, AddRes>> addClass...
Any pointers would be greatly appreciated
Prevent using Func<T> and Lazy<T> as dependencies to prevent slow object graph initialization. These are leaky abstractions, because they leak implementation details into the consumer. The implementation detail here is that such service is costly to create.
The fact that it takes too much time to create a dependency is an indication that your injection constructors do too much, while they should be simple, fast and reliable.
Another obvious problem is the Single Responsibility Principle violation in your components. Having more than 5 dependencies in a constructor is a code smell and an indication of a Single Responsibility Principle violation. Some containers get slower when you need to resolve really big object graphs, but when you make your components small and focussed, this problem will quite likely go away, since the object graph to construct will be much smaller.
First off some tips concerning DI in general:
You're right, you do not want to change the signature of the constructor. You're IoC container (Unity in your case) should enable you to design the interfaces and consumers as you like. Otherwise it isn't a good container.
When struggling starting with DI (and containers) I would advise wiring it up yourself. This gives you great insight in how it works and provides flexibility. Mark Seemann has written a lot about this stuff.
Your service's dependencies seem awfully crowded. Can't you refactor to less dependencies by combining some (maybe by a Facade)?
Making interfaces specific (not generic) makes things a lot simpler. Generics sometimes cause more harm than good.
I've coded up a quick example which compiles (I haven't tested it). I've used a generic interface in line with your example but used some fake implementation and string types as generic params (which aren't used):
If this is an implementation of an interface:
public class ClassLogic : IClassLogic<string, string>
{
public void Do()
{
// do stuff
}
}
Then you could implement a provider which only creates the implementation when needed (via a given Func) like this:
public class ClassLogicProvider : IClassLogic<string, string>
{
private readonly Func<IClassLogic<string, string>> innerLogicFactory;
public ClassLogicProvider(Func<IClassLogic<string, string>> innerLogicFactory)
{
this.innerLogicFactory = innerLogicFactory;
}
public void Do()
{
var classLogic = this.innerLogicFactory();
classLogic.Do();
}
}
And wire it up like this:
var container = new UnityContainer();
Func<IClassLogic<string, string>> classLogicFunc = () =>
{
// Create implementation on demand
return new ClassLogic();
};
container.RegisterType<IClassLogic<string, string>>(
new InjectionFactory(c => {
return new ClassLogicProvider(classLogicFunc);
})
);
This should give you the desired Lazy creation when to implementation is needed.
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);
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.
I am refactoring a class so that the code is testable (using NUnit and RhinoMocks as testing and isolations frameworks) and have found that I have found myself with a method is dependent on another (i.e. it depends on something which is created by that other method). Something like the following:
public class Impersonator
{
private ImpersonationContext _context;
public void Impersonate()
{
...
_context = GetContext();
...
}
public void UndoImpersonation()
{
if (_context != null)
_someDepend.Undo();
}
}
Which means that to test UndoImpersonation, I need to set it up by calling Impersonate (Impersonate already has several unit tests to verify its behaviour). This smells bad to me but in some sense it makes sense from the point of view of the code that calls into this class:
public void ExerciseClassToTest(Impersonator c)
{
try
{
if (NeedImpersonation())
{
c.Impersonate();
}
...
}
finally
{
c.UndoImpersonation();
}
}
I wouldn't have worked this out if I didn't try to write a unit test for UndoImpersonation and found myself having to set up the test by calling the other public method. So, is this a bad smell and if so how can I work around it?
Code smell has got to be one of the most vague terms I have ever encountered in the programming world. For a group of people that pride themselves on engineering principles, it ranks right up there in terms of unmeasurable rubbish, and about as useless a measure, as LOCs per day for programmer efficiency.
Anyway, that's my rant, thanks for listening :-)
To answer your specific question, I don't believe this is a problem. If you test something that has pre-conditions, you need to ensure the pre-conditions have been set up first for the given test case.
One of the tests should be what happens when you call it without first setting up the pre-conditions - it should either fail gracefully or set up it's own pre-condition if the caller hasn't bothered to do so.
Well, there is a bit too little context to tell, it looks like _someDepend should be initalized in the constructor.
Initializing fields in an instance method is a big NO for me. A class should be fully usable (i.e. all methods work) as soon as it is constructed; so the constructor(s) should initialize all instance variables. See e.g. the page on single step construction in Ward Cunningham's wiki.
The reason initializing fields in an instance method is bad is mainly that it imposes an implicit ordering on how you can call methods. In your case, TheMethodIWantToTest will do different things depending on whether DoStuff was called first. This is generally not something a user of your class would expect, so it's bad :-(.
That said, sometimes this kind of coupling may be unavoidable (e.g. if one method acquires a resource such as a file handle, and another method is needed to release it). But even that should be handled within one method if possible.
What applies to your case is hard to tell without more context.
Provided you don't consider mutable objects a code smell by themselves, having to put an object into the state needed for a test is simply part of the set-up for that test.
This is often unavoidable, for instance when working with remote connections - you have to call Open() before you can call Close(), and you don't want Open() to automatically happen in the constructor.
However you want to be very careful when doing this that the pattern is something readily understood - for instance I think most users accept this kind of behaviour for anything transactional, but might be surprised when they encounter DoStuff() and TheMethodIWantToTest() (whatever they're really called).
It's normally best practice to have a property that represents the current state - again look at remote or DB connections for an example of a consistently understood design.
The big no-no is for this to ever happen for properties. Properties should never care what order they are called in. If you have a simple value that does depend on the order of methods then it should be a parameterless method instead of a property-get.
Yes, I think there is a code smell in this case. Not because of dependencies between methods, but because of the vague identity of the object. Rather than having an Impersonator which can be in different persona states, why not have an immutable Persona?
If you need a different Persona, just create a new one rather than changing the state of an existing object. If you need to do some cleanup afterwards, make Persona disposable. You can keep the Impersonator class as a factory:
using (var persona = impersonator.createPersona(...))
{
// do something with the persona
}
To answer the title: having methods call each other (chaining) is unavoidable in object oriented programming, so in my view there is nothing wrong with testing a method that calls another. A unit test can be a class after all, it's a "unit" you're testing.
The level of chaining depends on the design of your object - you can either fork or cascade.
Forking:
classToTest1.SomeDependency.DoSomething()
Cascading:
classToTest1.DoSomething() (which internally would call SomeDependency.DoSomething)
But as others have mentioned, definitely keep your state initialisation in the constructor which from what I can tell, will probably solve your issue.
So I have a class with a method as follows:
public class SomeClass
{
...
private SomeDependency m_dependency;
public int DoStuff()
{
int result = 0;
...
int someValue = m_dependency.GrabValue();
...
return result;
}
}
And I've decided that rather than to call m_dependency.GrabValue() each time, I really want to cache the value in memory (i.e. in this class) since we're going to get the same value each time anyway (the dependency goes off and grabs some data from a table that hardly ever changes).
I've run into problems however trying to describe this new behaviour in a unit test. I've tried the following (I'm using NUnit with RhinoMocks):
[Test]
public void CacheThatValue()
{
var depend = MockRepository.GeneraMock<SomeDependency>();
depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1);
var sut = new SomeCLass(depend);
int result = sut.DoStuff();
result = sut.DoStuff();
depend.VerifyAllExpectations();
}
This however doesn't work; this test passes even without introducing any changes to the functionality. What am I doing wrong?
I see caching as orthogonal to Do(ing)Stuff. I would find a way to pull the caching logic outside of the method, either by changing SomeDependency or wrapping it somehow (I now have a cool idea for a caching class based around lambda expressions -- yum).
That way your tests for DoStuff don't need to change, you only need to make sure they work with the new wrapper. Then you can test the caching functionality of SomeDependency, or its wrapper, independently. With well-architected code putting a caching layer in place should be rather easy and neither your dependency nor your implementation should know the difference.
Unit tests shouldn't be testing implementation, they should test behavior. At the same time, the subject under test should have a narrowly-defined set of behavior.
To answer your question, you are using a Dynamic Mock and the default behavior is to allow any call that isn't configured. The additional calls are just returning "0". You need to set up an expectation that no more calls are made on the dependency:
depend.Expect(d => d.GrabValue()).Repeat.Once().Return(1);
depend.Expect(d => d.GrabValue()).Repeat.Never();
You may need to enter record/replay mode to get it to work properly.
This seems like a case for "tests drive the design". If caching is an implementation detail of SubDependency - and therefore can't be directly tested - then probably some of its functionality (specifically, its caching behavior) needs to be exposed - and since it's not natural to expose it within SubDependency, needs to be exposed in another class (let's call it "Cache"). In Cache, of course, the behavior is contractual - public, and thereby testable.
So the tests - and the smells - are telling us we need a new class. Test-Driven Design. Ain't it great?