I have a C# class which instantiates on its own a NetworkCommunicator class. I'd like to mock out the NetworkCommunicator class for my unit test, and replace it with a pretty simple stub.
But the NetworkCommunicator is never passed as a parameter. It's created by the class being tested.
In Ruby, this is easy to mock out. In Java, this is why you need Dependency Injection, which is too heavy for this project. Is there a simple way to mock this out in C#, perhaps using Moq or something similar?
You mentioned that DI is too heavyweight for this project, why not try some Truck Driver's DI, thus:
public interface IDependency
{
void DoSomeStuff();
}
public class ClassUnderTest
{
private IDependency _dependency;
public ClassUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public ClassUnderTest() : this(new Dependency())
{}
public void ImportantStuff()
{
_dependency.DoSomeStuff();
}
}
Using this constructor chaining technique, you can now mock the IDependency all you want, without worrying about hooking up DI or IoC.
Create a "TestClass" that inherits from your class under test.
Override that parameter with a mocked instance
Create a property on the class under test that returns the new instance
public class ClassUnderTest {
public string MethodYouAreTesting(int someInput) {
var networkCommunicator = GetNetworkCommunicator();
// Do some stuff that I might want to test
return "foo";
}
public virtual NetworkCommunicator GetNetworkCommunicator {
return new NetworkCommunicator();
}
}
[TestFixture]
public class ClassUnderTestTests {
public void GivenSomeCondition_MethodYouAreTesting_ReturnsFooString() {
var classToTest = new TestClassUnderTest();
var result = classToTest.MethodYouAreTesting(1);
Assert.That(result, Is.EqualTo("foo");
}
}
public class TestClassUnderTest : ClassUnderTest {
public override GetNetworkCommunicator {
return MockedNetworkCommunicator;
}
}
I read of this technique this in the "Art of Unit Testing" and use it frequently when refactoring to full DI doesn't make sense or when the class I'm testing isn't something I can change.
Hope this helps.
You should refactor your code and pass dependencies in. You can also use typemock as easier to use alternative to fakes in Visual Studio 2012.
There's the built-in Fakes system, pretty well described at http://msdn.microsoft.com/en-us/library/hh549175.aspx
If that is too heavy-weight for your use case you might find the PrivateObject class more useful.
I have a C# class which instantiates on its own a NetworkCommunicator class.
As you noticed, this is a show stopper in C# when you want to mock this thing out. Solution is simple, and depends on context/purpose of the instantiated class:
inject it as a dependency if it's reusable component
provide it via factory if it's something that should be created every time when demand comes in
Either way, you'll need DI (factory from the second example is naturally injected too).
In Java, this is why you need Dependency Injection, which is too heavy for this project.
Is dependency injection too heavy? DI is design pattern, it's only too heavy when used when it's not really needed. Your question clearly shows you need it. Perhaps you meant that DI container is too heavy for your project? This might be true, as depending on project's complexity, you should choose appropriate way to apply DI.
I'd like to raise one more point to be aware of when applying solution like the one proposed in Greg Smith's answer. Essentially, your API ends up with constructors:
public TestedClass() : this(new Dependency()) ...
public TestedClass(IDependency) ...
As appealing as it might be at first glance, when long-term perspective is taken into account, several issues start to emerge:
does TestedClass must have IDependency or can it do fine without it?
what default (parameterless constructor) defaults to (implementation detail-level knowledge is required to use it properly)?
it creates tightly coupled components (TestedClass assembly will possibly have to reference other assembly - Dependency's assembly, even though it might not be relevant to it anyhow)
This is an anti-pattern going under different names, e.g. Bastard Injection. Of course, some of those problems might be mitigated (like making constructor protected/internal or having default implementation in the same assembly), but the anti-pattern and its long-term consequences remain. Also note that it's by no means more simple, faster or less code than regular DI.
You'll have to ask yourself what's less heavy - applying proper DI, or going you ways around with anti-patterns and/or 3rd party frameworks (MS Fakes).
Related
I have two abstracts classes, 'ValidationsWithStorage' inherits 'Validations'
public abstract class Validations {
// methods..
}
public abstract class ValidationsWithStorage : Validations {
// ...
}
I also have a class:
public abstract class TestsValidations : T
T should be depend on the environment variable:
Environment.GetEnvironmentVariable("useStorage")
If this variable is null I want that T will be Validations.
Else, I want that T will be ValidationsWithStorage.
What is the best way to do it?
Thanks
I am not sure you can do this with inheritance. This is not the logic of inheritance. It will be better if you use something like factory pattern and change your current deisgn.
May be you can do something like this. I didn't test but i think it will be easier like this:
public interface Validations
{
void ValidationsStuff();
}
public class ValidationsWithStorage : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class TestsValidations : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class ValidationsFactory
{
public Validations geValidationsComponent(string useStorage)
{
if (string.IsNullOrEmpty(useStorage))
return new ValidationsWithStorage();
else
return new TestsValidations();
}
}
I don't think you can do what you want to do in the way you do it.
Why not let your class TestValidations take a parameter in its constructor of either type Validations or ValidationsWithStorage. If they both follow the same interface, your TestsValidations class wouldn't need to know (or care) which of the two it's working with.
So basically:
Create an interface for your Validations and ValidationsWithStorage class
Check your environment variable
Pass the correct class into the TestsValidation constructor according to the environment variable
Does that help?
You can do that using conditional compilation:
public abstract class TestsValidations
#if USESTORAGE
: ValidationsWithStorage
#else
: Validations
#endif
{
}
You can set it in project configuration or by passing additional parameters to msbuild: /p:DefineConstants="USESTORAGE"
I don't think this is good design, but it is doable.
If you want to work with inheritance I think your problem will be solved if you use the Generic Constraints
What not to do:
I don't recommend conditionally changing the definition of a class. There are weird, one-off reasons to do that, but we rarely encounter them and shouldn't make them a normal part of how we write code.
I also don't recommend a factory. A factory implies that you're making a decision at runtime, in production, whether to use a "real" class or a test class. A factory only makes sense if some data available only at runtime determines which implementation you want to use. For example, if you want to validate an address, you might use its country to determine whether to us a US validator, Canadian validator, etc, like this:
var validator = _validatorFactory.GetValidator(address.Country);
Also, that means that the "test" class would be referenced from your production code. That's undesirable and a little strange.
What to do:
If you aren't making such a decision at runtime then this should be determined in the composition root - that is, in the part of our application that determines, at startup, which classes we're going to use.
To start with, you need an abstraction. This is most often an interface, like this:
public interface IValidator
{
ValidationResult Validate(Something value);
}
The class that needs the validation would look like this:
public class ClassThatNeedsValidation
{
private readonly IValidator _validator;
public ClassThatNeedsValidation(IValidator validator)
{
_validator = validator;
}
// now the method that needs to use validation can
// use _validator.
}
That's dependency injection. ClassThatNeedsValidation isn't responsible for creating an instance of a validator. That would force it to "know" about the implementation of IValidator. Instead, it expects to have an IValidator provided to it. (In other words its dependency - the thing it needs - is injected into it.)
Now, if you're creating an instance of ClassThatNeedsValidation, it might look like this:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
Then, in your unit test project, you might have a test implementation of IValidator. (You can also use a framework like Moq, but I'm with you - sometimes I prefer to write a test double - a test class that implements the interface.)
So in a unit test, you might write this:
var foo = new ClassThatNeedsValidation(new TestValidator());
This also means that TestValidator can be in your test project, not mixed with your production code.
How to make it easier:
In this example:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
You can see how this might get messy. What if ValidationWithStorage has its own dependencies? Then you might have to start writing code like this:
var foo = new ClassThatNeedsValidation(
new ValidationWithStorage(
connectionString,
new SomethingElse(
new Whatever())));
That's not fun. That's why we often use an IoC container, a.k.a dependency injection container.
This is familiar if we use ASP.NET Core, although it's important to know that we don't have to use ASP.NET Core to do this. We can add Microsoft.Extensions.DependencyInjection, Autofac, Windsor, or others to a project.
Explaining this is somewhat beyond the scope of this answer, and it might be more than what you need right now. But it enables us to write code that looks like this:
services.AddSingleton<IValidator, ValidationWithStorage>();
services.AddSingleton<Whatever>();
services.AddSingleton<ISomethingElse, SomethingElse>();
services.AddSingleton<ClassThatNeedsValidation>();
Now, if the container needs to create an instance of ClassThatNeedsValidation, it will look at the constructor, figure out what dependencies it needs, and create them. If those classes have dependencies it creates them too, and so on.
This takes a minute or several or some reading/trying if it's a new concept, but trust me, it makes writing code and unit tests much easier. (Unless we do it wrong, then it makes everything harder, but that's true of everything.)
What if, for some reason, you wanted to use a different implementation of IValidator in a different environment? Because the code above is executed once, at startup, that's easy:
if(someVariable = false)
services.AddSingleton<IValidator, OtherValidator>();
else
services.AddSingleton<IValidator, ValidationWithStorage>();
You're making the decision, but you're making it once. A class that depends on IValidator doesn't need to know about this decision. It doesn't need to ask which environment it's in. If we go down that route, we'll end up with stuff like that polluting all of our classes. It will also make our unit tests much more difficult to write and understand. Making decisions like this at startup - the composition root - eliminates all of that messiness.
Is this a good idea?
public sealed class ConcreteClass : IConcreteClass
{
private ConcreteClass ()
{
}
public void ExecuteSomething()
{
}
}
in dependancy resolver:
kernel.Bind<IConcreteClass>().To<ConcreteClass>();
If there are some that didn't know this can be done - it can.
This forces anyone who needs to use this code to inject it. It can't be instantiated manually.
Do you see anything wrong with this?
Based on the comments is seems that you want to force injection. The way to do this is to have your classes require their dependencies through their constructor, not to obfuscate intent by making your classes follow strange conventions.
DI is a technique, frameworks make that simpler, but the important thing is to educate people as to why they should follow the principle. You can 'force' the changes you want by making your constructors so that they require the dependencies. How they then construct them is up to the client, but if the constructor has the dependency in it then they will have to inject an instance to use the class.
I just proposed the following pattern for someone else. I have used it a few times, when I wanted the ability to inject dependencies for test, but but still wanted this backdoor (somewhat) invisible to outsiders. Hence, the empty public ctor and internal ctor with the argument:
public class ClassThatUseInjection
{
private readonly SomeClass _injectedClass;
public ClassThatUseInjection(): this(new SomeClass()) {}
internal ClassThatUseInjection(SomeClass injectedClass)
{
_injectedClass = injectedClass;
}
}
public class SomeClass
{
public object SomeProperty { get; set; }
}
My idea was that since the empty ctor does nothing but forward with a new instance, my crime is not too bad. What do you think? Is is too smelly?
Regards,
Morten
I think it is ok. In fact, what you are doing with injecting the class is Dependency Injection and a practical use of the Open/Closed Principle.
I don't even see no harm in making that internal ctor into a public one.
My problem with this is always, that I don't want to force others to create an instance of the injected class, therefore, the default ctor. But if they want to create an instance, they can go ahead and do so.
On a related note: IMHO, you should use an interface instead of a class, otherwise, I don't see too much advantage in passing that class in the first place...
It's called "poor man's dependency injection", if you can't get a proper IOC container into your app its a reasonable alternative although you would be better off with the power a container gives you.
Jimmy Bogard has a good write up here
wanted this backdoor (somewhat) invisible to outsiders
Making it internal successfully does that, IMO.
The down-side is that it puts your tests in the same assembly.
See also Hide public method used to help test a .NET assembly about how to hide public methods if your tests are in an external assembly.
Edit: what you've done is especially appropriate, if SomeClass is logically internal ... if it's an implementation detail which shouldn't/needn't be exposed in the assembly's public interface.
I've used this Service Locator Pattern in my Application and implemented as a Singleton:
Service Locator Pattern
And now I want test it .So far I've written a test verifying that my class is a Singleton. I've also written this test:
[Test]
[ExpectedException(typeof(ApplicationException))]
public void GetService_Throws_Exception_When_Invalid_Key_Is_Provided()
{
locator.GetService<IRandomService>();
}
But I don't really like the last test since I'm never going to use the IRandomService. So I'm looking for a nicer way to test that the GetService<T> throws an exception. Also I like to know if there is any other relevants tests I could write for this class.
I'm using the latest version of NUnit.
Cheers
Some things:
A test to verify the class is a singleton? The singleton pattern will ensure that attempting to treat a singleton as an instance class won't even compile. If you have not written your service locator something like the following, it's wrong:
The Singleton Pattern in C#:
public class MySingleton()
{
//Could also be a readonly field, or private with a GetInstance method
public static MySingleton Instance {get; private set;}
static MySingleton()
{
Instance = new MySingleton();
}
private MySingleton() { ... }
}
...
//in external code
var mySingletonInstanceRef = MySingleTon.Instance; //right
var mySingletonInstanceRef = new MySingleton(); //does not compile
//EDIT: The thread-safe lazy-loaded singleton
public class MySingleton()
{
//static fields with initializers are initialized on first reference, so this behaves lazily
public static readonly MySingleton instance = new MySingleton();
//instead of the below you could make the field public, or have a GetInstance() method
public static MySingleton Instance {get{return instance;}
private MySingleton() { ... }
}
The service locator is an anti-pattern. It sounds great, but it doesn't really solve the problems that it was created to solve. The chief problem is that it tightly couples you to the service locator; if the locator changes, every class that uses it changes. By contrast, Dependency Injection can be done without a fancy framework; you just make sure any complex, expensive, reusable, etc. object is passed in to the object that needs it via its constructor. DI/IoC frameworks just streamline this process by ensuring that all known dependencies of a required object are provided, even if an object in the graph can't know about dependencies of its children.
You have already developed the class. The spirit of TDD/BDD is that you write tests that will prove that code you haven't yet written will be correct. I'm not saying writing tests now wouldn't serve a purpose, but a failing test requires the object be opened up and fixed, and if the code is already integrated you could break other things.
Unit tests make heavy use of constructs that will never see production. Mocks, stubs, proxies and other "test helpers" exist to isolate the object under test from the environment into which it is normally integrated, guaranteeing that if the inputs are A, B, and C, the object under test will do X, regardless of whether what it normally hooks into will give it A, B, and C. Therefore, don't worry about creating simple constructs like a skeleton interface that you wouldn't use in production; as long as it is a good representation of the input you would expect in the test case, it's fine.
But I don't really like the last test since I'm never going to use the IRandomService.
But that's kind of the point. You wire up your locator in the test setup method (arrange), and then you lookup a key that was not wired up (act), then you check that an exception was thrown (assert). You don't need to use types you're actually going to use, you just want to get some confidence that your method is working.
Also I like to know if there is any other relevants tests I could write for this class.
Well, I'm going to answer a different question here.
Is the service locator pattern evil?
Yes, it is pure evil.
It defeats the purpose of dependency injection because it doesn't make dependencies explicit (any class can pull anything out of the service locator). Moreover, it makes your all of your components dependent on this one class.
It makes maintenance an unbelievable nightmare because now you have this one component that is just spread all over your codebase. You have become tightly coupled to this one class.
Further, testing is a nightmare. Let's say you have
public class Foo {
public Foo() { // }
public string Bar() { // }
}
and you want to test Foo.Bar.
public void BarDoesSomething() {
var foo = new Foo();
Assert.Equal("Something", foo.Bar());
}
and you run your test and you get an exception
ServiceLocator could not resolve component Frob.
What? Oh that's because your constructor looks like this:
public Foo() {
this.frob = ServiceLocator.GetService<Frob>();
}
And on and on.
avoid, Avoid, AVOID.
I don't quite understand your question. Are you dissatisfied with requesting a type that you'll never use in production? Are you dissatisfied with using the service locator in a fashion that is not indicative of production code? The test itself looks ok to me -- you're requesting something that doesn't exist and proving that the expected behaviour occurs. For a unit test, such a thing is perfectly reasonable to do.
One thing we did when using a dependency injection container was to separate our application wiring phase into modules, then we'd try and resolve the root type in an integration test to ensure that the app could be wired up. If the wiring test failed, it was a good sign that the app wasn't working (though it didn't prove that the app worked, either). It'd be tricker to do this sort of thing when using a service locator.
I agree 100% with Jason, too -- service locators seem like a good idea, but quickly turn nasty. They 'pull' (types using the service locator instance must be coupled to it), whereas Dependency Injection containers 'push' (the vast majority of the application is DI agnostic, so the code is far less brittle and more re-usable).
A couple of other things:
[ExpectedException] is deprecated.
use Assert.Throws
instead
ApplicationException is
also deprecated.
Let's say we have
public interface ITimestampProvider
{
DateTime GetTimestamp();
}
and a class which consumes it
public class Timestamped
{
private ITimestampProvider _timestampProvider
public Timestamped(ITimestampProvider timestampProvider)
{
// arg null check
_timestampProvider = timestampProvider;
}
public DateTime Timestamp { get; private set; }
public void Stamp()
{
this.Timestamp = _timestampProvider.GetTimestamp();
}
}
and a default implementation of:
public sealed class SystemTimestampProvider : ITimestampProvider
{
public DateTime GetTimestamp()
{
return DateTime.Now;
}
}
Is it helpful or harfmful to introduce this constructor?
public Timestamped() : this(new SystemTimestampProvider())
{}
This is a general question, i.e. timestamping is not the interesting part.
I think it depends on the scenario, and is basically a function of who the consumer the code is (library vs. application) and whether you're using an IoC container or not.
If you're using an IoC container, and this is not part of a public API, then let the container do the heavy lifting, and just have the single constructor. Adding the no-args constructor just makes things confusing, since you'll never use it.
If this is part of a public API, then keep both. If you're using IoC, just make sure your IoC finds the "greediest" constructor (the one with the most arguments). Folks not using IoC, but using your API will appreciate not having to construct an entire dependency graph in order to use your object.
If you're not using an IoC container, but just want to to unit test with a mock, keep the no-args constructor, and make the greedy constructor internal. Add InternalsVisibleTo for your unit test assembly so that it can use the greedy constructor. If you're just unit testing, then you don't need the extra public API surface.
i wouldn't provide that constructor. Doing so makes it far too easy to call new TimeStamped and get an instance with new SystemTimestampProvider() when your IoC may be configured to use OtherTimestampProvider().
End of the day you'll end up with one hell of a time trying to debug why you're getting the wrong timestamp.
If you only provide the first constructor you can do a simple find usages of SystemTimestampProvider to find out who is (wrongly) using that provider instead of the IoC configured Provider.
In general I don't think so... It depends on what you're using Dependency Injection for. When I use DI for unit testing, I do the same thing (more or less) by instantiating the production version of the dependant object when the injected instance is null... And then I have an overload that does not take a parameter and delegates to the one that does... I use the parameterless one for production code, and inject a test version for unit test methods...
If you're talking about a IOC container application, otoh, you need to be careful about interfering in what the configuration settings are telling the container to do in a way that's not clear ...
public class EventsLogic
{
private readonly IEventDAL ievtDal;
public IEventDAL IEventDAL { get { return ievtDal; } }
public EventsLogic(): this(null) {}
public EventsLogic(IIEEWSDAL wsDal, IEventDAL evtDal)
{
ievtDal = evtDal ?? new EventDAL();
}
}
I try to avoid this - there are a few places where I've found it to be a useful design but more often than not I've found it just leads to me making mistakes that can be a little puzzling to work out.
The need for the default injected objects is greatly reduced by using a dependency injection container (I use StructureMap) to manage all this wiring - the DI container makes sure that you always get a concrete instance you can use.
The only place where I'm still tempted to use the constructor you suggest is in my unit tests but recently I've been getting far greater value out of using fake or mocked objects.
There are places where having the default dependant objects is the correct and useful design, but in general I'd say that you are just introducing tight coupling that doesn't add a lot of value.
It's neither helpful nor harmful. It poses an aesthetic problem in that you are limiting your DI to constructor injection only when your design may allow for property setter injection.
Another option would be to implement a getter that returns a default implementation:
public DateTime Timestamp
{
get { return _timestampProvider??new SystemTimestampProvider(); }
set { _timestampProvider = value; }
}
Alternately, you can implement the above using a singleton if you're worried about creating too many objects in the heap.
My team has a great deal of success using this method. I recommend one change: Make _timestampProvider readonly. This forces the provider to be deterministic at construction and will eliminate bugs.
public class Timestamped
{
private readonly ITimestampProvider _timestampProvider;
public Timestamped(ITimestampProvider timestampProvider)
{
_timestampProvider = timestampProvider;
}
public Timestamped(): this(new SystemTimestampProvider())
{ }
}
That said, we are always looking at new technologies, including DI frameworks. If we ever abandon this technique for something significantly better I'll let you know.