Unit Testing Factory/Service Locator - Static class - c#

Recently, I saw this code. Since I am trying to learn few things at once, I am having issues with this code but dont know how to resolve. I would like to be able to unit test this code
public static class CarFactory
{
private static readonly IDictionary<string, Type> CarsRegistry = new Dictionary<string, Type>();
public static void Register<TCar>(string car) where TCar : CarBase, new()
{
if (!CarsRegistry.ContainsKey(car))
{
CarsRegistry.Add(car, typeof(TCar));
}
}
public static ICar Create(string car)
{
if (CarsRegistry.ContainsKey(car))
{
CarBase newCar = (CarBase)Activator.CreateInstance(CarsRegistry[car]);
return newCar;
}
throw new NotSupportedException($"Unknown '{car}'");
}
}
I have few problems with this code.
Name is CarFactory but this does not look like a Factory Pattern to me. It looks more like Locator Pattern
The class is static - and I heard static classes are bad for unit testing in frameworks like Moq and that they also hide dependencies. Say a method in another regular class uses this, for unit test, there is no way to know that that method depend on this static class
I would like to ensure this class is called properly and I think based on my reading that this is Locator Pattern.
I would also like to unit test this class and need help to make it unit testable using Moq.
Thanks to #ErikPhillips explanation below, I now understand that other classes using this class will be not testable. So, if I have a class like below:
public class CarConsumer
{
public void ICar GetRedCar()
{
var result = CarFactory.Create("Tesla");
result.Color = Color.Red;
return result;
}
}
, GetRedCar() method will be difficult to test because it uses CarFactory static class and for a unit test or an outside client, there is nothing in GetRedCar() method API that suggest it is depending on this static class.
I would like to refactor CarFactory class so other classes using it like in example above CarConsumer class can be tested properly.

I would like to be able to unit test this code
What specific problems prevent you from unit testing this class? It has two methods, seems pretty straight forward to write a unit test against.
Name is CarFactory but this does not look like a Factory Pattern to me
I believe a Factory Pattern is
The factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created
I pass in the name of the car (so I haven't specified the type) and it creates the class for me. That's pretty much it. Is it a good example of one? Not in my opinion, but my opinion of how well it's done doesn't change what it is.
This doesn't mean it's not Service Locator, but it definitely is a Factory Method.
(Honestly it doesn't look like a service locator because it only delivers a single service)
unit testing in frameworks like Moq
Moq is not a Unit-Testing framework. Moq is a Mocking Framework. Static classes are not easy to Mock. If you can Mock it, you can unit-test with methods that require a mocked class.
static classes .. that they also hide dependencies.
Any poorly designed anything can do anything. Static Classes aren't by definition designed to hide anything.
I would say in this instance, that this Static Class, prevents you from being able to Mock it easily to unit test other methods that rely on the Static Classes methods.
I would also like to unit test this class and need help to make it unit testable using Moq.
Again, there is nothing preventing you from unit-testing this class.
public class CarFactoryTests
{
public class MoqCar : CarBase { }
public void Register_WithValidParameters_DoesNotThrowException
{
// Act
Assert.DoesNotThrow(() => CarFactory.Register<MoqCar>(
nameof(Register_WithValidParameters_DoesNotThrowException)));
}
public void Create_WithValidCar_DoesNotThrowException
{
CarFactory.Register<MoqCar>(
nameof(Create_WithValidParameters_DoesNotThrowException));
Assert.DoesNotThrow(() => CarFactory.Create(
nameof(Create_WithValidParameters_DoesNotThrowException));
}
// etc etc
}
The problem you may run into is
public class CarConsumer
{
public void ICar GetRedCar()
{
var result = CarFactory.Create("Tesla");
result.Color = Color.Red;
return result;
}
}
Testing this method means that you are not in full control of the method because there is external code GetRedCar() relies on. You cannot write a pure unit test here.
This is why you'd have to convert CarFactory to an instance class. And then make sure it's has the correct lifetime for whatever DI framework you're using.
public class CarConsumer
{
private ICarFactory _carFactory;
public CarConsumer(ICarFactory carFactory)
{
_carFactory = carFactory;
}
public void ICar GetRedCar()
{
var result = _carFactory.Create("Tesla");
result.Color = Color.Red;
return result;
}
}
Now we can Moq ICarfactory and write pure unit test against GetRedCar().
The following is not recommended.
If for whatever reason you are stuck with this type of Factory but you still want to write pure unit tests, you can do something like:
public class CarConsumer
{
private Func<string, ICar> _createCar;
public CarConsumer(Func<string, ICar> createCar= CarFactory.Create)
{
_createCar = createCar;
}
public void ICar GetRedCar()
{
var result = _createCar("Tesla");
result.Color = Color.Red;
return result;
}
}
We can Moq this type of Func, but it's really just a crutch for the real problem.
I guess the real question I have is how to make my CarFactory so that methods from other classes using it can be tested using Moq?
public interface ICarFactory
{
void Register<TCar>(string car) where TCar : CarBase, new();
ICar Create(string car);
}
public class CarFactory : ICarFactory
{
private readonly IDictionary<string, Type> CarsRegistry
= new Dictionary<string, Type>();
public void Register<TCar>(string car) where TCar : CarBase, new()
{
if (!CarsRegistry.ContainsKey(car))
{
CarsRegistry.Add(car, typeof(TCar));
}
}
public ICar Create(string car)
{
if (CarsRegistry.ContainsKey(car))
{
CarBase newCar = (CarBase)Activator.CreateInstance(CarsRegistry[car]);
return newCar;
}
throw new NotSupportedException($"Unknown '{car}'");
}
}

Related

Interface for System.Convert

Is there a built in interface that implements Convert.ToInt64()?
I'm trying to mock a class that is responsible for converting a string to a long, but I don't know which interface to use. It doesn't have to be Convert.
I can't imaging I'm the only one who needs a testable class that converts strings to longs.
To help with mocking, do not call Convert.ToInt64() directly. Instead, create a simple wrapper interface and use dependency injection:
public interface IStringToLong {
long StringToLong(string val);
}
public class StringToLong : IStringToLong {
public long StringToLong(string val) => Convert.ToInt64(val);
}
// While using dependency injection
public class SomeClass {
private readonly IStringToLong _stringToLong;
public SomeClass(IStringToLong stringToLong) {
_stringToLong = stringToLong;
}
public void SomeMethod {
// Instead of Convert.ToInt64("10000"), use this:
var someLong = _stringToLong.StringToLong("10000");
}
}
Now when testing SomeClass you can use a mocked object created from the IStringToLong interface.
Convert is a static class, so it cannot have an interface. I'm not sure what you are trying to do without looking at some code, but if you truly need to mock Convert.ToInt64, you could use Func<string, long>, then in your tests pass a mock function, i.e. anyString => 21122.

Mocking return values of a concrete class method using Moq

I have an abstract factory like this.
public abstract class AbstractFactory
{
public abstract ISyncService GetSyncService(EntityType entityType);
}
And I have its concrete implementation like this.
public class SyncFactory : AbstractFactory
{
private readonly IOperatorRepository _operatorRepository;
public SyncFactory( IOperatorRepository operatorRepository)
{
_operatorRepository = operatorRepository;
}
public override ISyncService GetSyncService(EntityType entityType)
{
return new OperatorSyncService(_operatorRepository);
}
}
This concrete factory is accessed in a method like this.
public void MethodTobeTested()
{
var syncService =
new SyncFactory(_operatorRepository).GetSyncService(entityType);
}
Now I need to write a unit test for MethodTobeTested().
I mocked the return value of the GetSyncService() like this. But it's calling the actual OperatorSyncService, not the mock. I need this mock to mock another method inside OperatorSyncService
private Mock<SyncFactory> _syncServiceMock;
_syncServiceMock = new Mock<SyncFactory>();
_syncServiceMock.Setup(m => m.GetSyncService(operator)).Returns(_operatorSyncServiceMock.Object);
Any idea on how to resolve this?
In your SyncFactory implementation you inject an instance of IOperatorRepository. This is great because it allows you to inject a different version if needs be and creates a seem for you to use a mock implementation of IOperatorRepository.
You have also made an abstract factory which looks good but it looks like the problem is with your usage of the factory;
var syncService =
new SyncFactory(_operatorRepository).GetSyncService(entityType);
In your MethodToBeTested you create a concrete implementation of SyncFactory, this make the point of the abstract factory a little redundent since you cannot inject a different implementation. I don't know where you are geting your _operatorRepository instance from but I can see two ways forward.
In the constructor of the class that contains MethodToBeTested add a parameter that takes an instance of your abstract factory, then get your MethodToBeTested to use this injected factory instead of creating a new one, this would allow you to mock the whole factory - this is my recommended approach because the class containing MethodToBeTested would no longer need to know how to create a factory instance which it shouldn't if you are following the single responsibility principle. There would be no dependence on any concrete implementation.
As above but instead inject IOperatorRepository rather than the factory, you can then inject a mock IOperatorRepository but I would advise against this since you've done such a good job of creating all your abstractions to then cast this work aside and "new up" an instance of syncFactory and creating a concrete dependency
MethodToBeTested is tightly coupled to SyncFactory because the method is manually creating a new instance of SyncFactory. This makes mocking the dependency very difficult.
Assuming
public class ClassToBeTested {
public void MethodTobeTested() {
var syncService = new SyncFactory(_operatorRepository).GetSyncService(entityType);
//...other code
}
}
ClassToBeTested should be refactored to
public class ClassToBeTested {
private readonly AbstractFactory syncFactory;
public ClassToBeTested (AbstractFactory factory) {
this.syncFactory = factory
}
public void MethodTobeTested() {
var syncService = syncFactory.GetSyncService(entityType);
//...other code
}
}
This will allow the dependency to be mocked and injected into the class to be tested and accessed by the method to be tested. The class to be tested now only needs to know what it needs to know. It now no longer needs to be aware of IOperatorRepository.
The new in the method MethodTobeTested creates new instance so no mock can be injected. Inject the factory e.g. as parameter so it can be mocked in the test.
public void MethodTobeTested(AbstractFactory factory)
{
EntityType entityType = null;
var syncService = factory.GetSyncService(entityType);
}
[TestMethod]
public void Method_Condition_Result()
{
// Arrange
TestedClass tested = new TestedClass();
Mock<ISyncService> syncServiceMock = new Mock<ISyncService>();
Mock<AbstractFactory> factoryMock = new Mock<AbstractFactory>();
factoryMock.Setup(f => f.GetSyncService(It.IsAny<EntityType>())).Returns(syncServiceMock.Object);
// Act
tested.MethodTobeTested(factoryMock.Object);
// Assert
// ...
}

Unit test to verify that a base class method is called

I have a base class:
public abstract class MyBaseClass
{
protected virtual void Method1()
{
}
}
and a derived class:
public class MyDerivedClass : MyBaseClass
{
public void Method2()
{
base.Method1();
}
}
I want to write a unit test for Method2 to verify that it calls Method1 on the base class. I'm using Moq as my mocking library. Is this possible?
I came across a related SO link:
Mocking a base class method call with Moq
in which the 2nd answer suggests it can be achieved by setting CallBase property to true on the mock object. However it's not clear how this would enable the call to the base class method (Method1 in the above example) to be verified.
Appreciate any assistance with this.
Unit tests should verify behavior, not implementation. There are several reasons for this:
The results are the goal, not how you get the results
Testing results allows you to improve the implementation without re-writing your tests
Implementations are harder to mock
You might be able to put in hooks or create mocks that verify that the base method was called, but do you really care how the answer was achieved, or do you care that the answer is right?
If the particular implementation you require has side effects that you can verify, then that is what you should be validating.
Mocking the base class from the perspective of the derived class is not possible. In your simple example, I would suggest one of the two options.
Option 1: In the event that MyDerivedClass really shouldn't care what MyBaseClass is up to, then use dependency injection! Yay abstraction!
public class MyClass
{
private readonly IUsedToBeBaseClass myDependency;
public MyClass(IUsedToBeBaseClass myDependency){
_myDependency = myDependency;
}
public void Method2()
{
_myDependency.Method1();
}
}
Elsewhere in test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var dependency = new Mock<IUsedToBeBaseClass>();
var unitUnderTest = new MyClass(dependency.Object);
var unitUnderTest.Method2();
dependency.Verify(x => x.Method1(), Times.Once);
}
}
Option 2: In the event that MyDerivedClass NEEDS to know what MyBaseClass is doing, then test that MyBaseClass is doing the right thing.
In alternative test land...
[TestClass]
public class TestMyDependency {
[TestMethod]
public void TestThatMyDependencyIsCalled() {
var unitUnderTest = new MyDerivedClass();
var unitUnderTest.Method2();
/* verify base class behavior #1 inside Method1() */
/* verify base class behavior #2 inside Method1() */
/* ... */
}
}
What you're describing is not a test of your code, but a test of the behavior of the language. That's fine, because it's a good way to ensure that the language behaves the way we think it does. I used to write lots of little console apps when I was learning. I wish I'd known about unit testing then because it's a better way to go about it.
But once you've tested it and confirmed that the language behaves the way you expect, I wouldn't keep writing tests for that. You can just test the behavior of your code.
Here's a real simple example:
public class TheBaseClass
{
public readonly List<string> Output = new List<string>();
public virtual void WriteToOutput()
{
Output.Add("TheBaseClass");
}
}
public class TheDerivedClass : TheBaseClass
{
public override void WriteToOutput()
{
Output.Add("TheDerivedClass");
base.WriteToOutput();
}
}
Unit test
[TestMethod]
public void EnsureDerivedClassCallsBaseClass()
{
var testSubject = new TheDerivedClass();
testSubject.WriteToOutput();
Assert.IsTrue(testSubject.Output.Contains("TheBaseClass"));
}

Initialising fields with initial values with Ninject

I'm currently trying to work out how to set the initial values for some fields using Ninject.
I have something like this:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
}
public void DoAThing()
{
_something.DoSomething();
}
}
My dilemma comes about in the setting of _something to an initial value, given I don't want the class to know anything about which default implementation of ISomething to use, is there a way of achieving this in Ninject?
I should add that passing the initial values in via the constructor is not an option.
I should also add that this is in a class-library, so any information on how and when the setup of the kernel & injection should take place would be great :)
Elaboration: It seems that people could be getting confused, I am not trying to get an ISomething into the class (it isn't a dependency), rather, the default implementation of ISomething is the dependency, this is why I went for the service-locator pattern, for actual dependencies I would of course have them in the constructor.
Thanks.
Yes, it's not very good to have highly coupled classes, thus depending on abstractions is a good choice. But hiding your dependencies is not very good solution. Make them visible to clients of your class, and use dependency injection to provide concrete implementations of dependencies to your class:
public class SomeClass
{
private ISomething _something;
public SomeClass(ISomething something, string someParam)
{
_something = something;
}
public void DoAThing()
{
_something.DoSomething();
}
}
Also consider to create factory, which will provide default implementation of ISomething to created SomeClass objects.
In the end I decided to go with a static IOC access class to allow my code to gain access to the core Ninject Kernel used by the class library for the main injection.
So:
internal static class IOC
{
private static readonly IKernel _kernel;
static IOC()
{
_kernel = new StandardKernel(new IModule[] {
new SomethingModule(),
});
}
static T Get<T>()
{
return _kernel.Get<T>();
}
}
internal sealed class SomethingModule : StandardModule
{
public override void Load()
{
Bind<ISomething>().To<ConcreteSomething>(
new ConstructorParam("arg", "value"));
}
}
Then in my previous class:
public class SomeClass
{
private ISomething _something;
public SomeClass(string someParam)
{
_something = IOC.Get<ISomething>();
}
public void DoAThing()
{
_something.DoSomething();
}
}
Now I can get concrete implementations and even have them initialised with default values to boot!
The way of getting the concrete classes initialised with default values is a little flimsy, but I'm sure there are smarter ways of achieving this in Ninject, but it does appear that a hybrid solution of service-locator-esque code and Ninject works quite well!
BTW I believe you could also have multiple IOC containers in differing scopes (themselves passed along via Ninject :P) to prevent creating a behemoth "everything everywhere" kernel.
Hope this helped someone!

What's a good way to write Unit tests for code with protected objects C# (using NMock, and NUnit framework)

When writeing unit tests for a single class that contains other objects what's the best way to use
mock objects to avoid tests dependant on other classes.
Example 1:
public class MyClass
{
protected MyObject _obj;
public MyClass()
{
_obj = new MyObject();
}
public object DoSomething()
{
//some work
_obj.MethodCall();
//more work;
return result;
}
}
I'd rather not expose the protected value to create a unit test for the code. A wrapper class would
work for testing but is there a better way?
Example 2:
public class MyClass
{
public object DoSomething()
{
//some work
MyObject obj = new obj(parameters);
_obj.MethodCall(Method1);
//more work;
return result;
}
public int Method1()
{ ... }
}
Similar to the above example but the ojbect is created in the method I am calling.
Example 3:
public class MyClass
{
public object DoSomething()
{
//some work
obj.MethodCall(Method1);
//more work;
return result;
}
public int MethodA()
{ ... }
}
Is there a way to test MethodA when it is only used as a delegate?
I recommend that you take a look at dependency injection. One thing is using mock objects, but unless you're using something like TypeMock, which basically lets you modify you code on the fly, you want to have a way to inject the instances your class depends on if you want to get rid of the dependencies. So in examples 1, I would suggest that instead of newing an instance of MyObject in the constructor, you could have the caller supply that instance. In that case you would easily by able to replace it with a mock or even a stub.
Have you tried deriving a UTMyClass from MyClass?

Categories