Constructing mocks in unit tests - c#

Is there any way to have a mock constructed instead of a real instance when testing code that calls a constructor?
For example:
public class ClassToTest
{
public void MethodToTest()
{
MyObject foo = new MyObject();
Console.WriteLine(foo.ToString());
}
}
In this example, I need to create a unit test that confirms that calling MethodToTest on an instance of ClassToTest will indeed output whatever the result of the ToString() method of a newly created instance of MyObject.
I can't see a way of realistically testing the 'ClassToTest' class in isolation; testing this method would actually test the 'myObject.ToString()' method as well as the MethodToTest method.

Not really. Your ClassToTest is hard to test because of its design. If you want to be able to swap out its dependencies for mock objects, then you need to think about how these dependencies are injected - but just creating them in the constructor is not an approach that is going to help you. You could use constructor injection:
public class ClassToTest
{
MyObject _foo;
public void MethodToTest(Myobject foo)
{
_foo = foo;
Console.WriteLine(foo.ToString());
}
}
or you could use property injection:
public class ClassToTest
{
public MyObject Foo { get; set; }
public void MethodToTest()
{
}
}
The former may suit your example more given you want to write out the console there; it is often the best approach when your dependency is a must have dependency for the object rather than an optional one.
You could do a lot worse than exploring the concepts of dependency injection and inversion of control.

Related

How to mock SecretClient when it doesn't have an interface? [duplicate]

I have an interface which I am mocking with 'NSubstitute' which contains properties that return concreate classes, that is the return value is not an interface. e.g
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
The 'SomeObj' concrete class has a default constructor but 'NSubstitute' always returns 'null' for these properties. The class itself is not under my control so I cannot simply make it derive from an interface.
Can 'NSubstitute' mock these type of properties? Or is there a way to override the behaviour? Otherwise I have to manually initialise the mock before the test and that can be a lot of code (even if its reused through a common method).
Perhaps there is a simpler solution that I have over-looked?
Classes will be auto-mocked if they have a default (parameterless) constructor and all its members are virtual (see the note in the intro of Auto and recursive mocks). The aim of this is to reduce the potential for unwanted (destructive?) side-effects if we are using a substitute and suddenly hit a non-virtual, unmocked code path that does bad stuff in an instance we thought was fake.
NSubstitute doesn't have a way override this behaviour. Instead, I'd recommend creating all your substitutes via your own factory method (e.g. a static Sub.For<T>(...) method in your test project) that uses NSubstitute to produce a substitute, then applies all the specific initialisation rules you need, like using reflection to stub out values for each class property.
Hope this helps.
Possibly related links:
I advise trying to avoid mocking types we don't own.
Stack Overflow: Is it recommended to mock concrete class?
Hacky factory method sample that subs properties using reflection.
It doesn't count as auto-mocking but you did also ask "Or is there a way to override the behaviour?" and "Perhaps there is a simpler solution that I have over-looked?"
This answer relies on the statements in your question that:
SomeObj is a class outside of your control, from which I assume it is either separately tested or else not testable
SomeObj has a default constructor
Sure, it requires you to "manually initialise the mock before the test" but since you've not told us what this object is it's not possible to know how much work it would take to implement fully.
public class SomeObj
{
// Non-virtual to prevent auto-mocking
public void Dummy() { }
}
public interface ISomething
{
SomeObj First { get; }
SomeObj Second { get; }
}
[TestMethod]
public void Test_17182355ms()
{
ISomething mockedSomething = Substitute.For<ISomething>();
SomeObj firstObj = mockedSomething.First;
Assert.IsNull(firstObj);
mockedSomething.First.Returns(new SomeObj());
mockedSomething.Second.Returns(new SomeObj());
firstObj = mockedSomething.First;
Assert.IsNotNull(firstObj);
}
Another approach, though not without its own drawbacks, would be to extract your own interface for SomeObj, something like this:
public interface ISomeObj
{
void Dummy();
}
public class MySomeObj : SomeObj, ISomeObj
{
}
and then mock ISomeObj in your test.

Unit Testing Factory/Service Locator - Static class

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}'");
}
}

How to ignore calling function in constructor?

I have class that constructor calls a function in constructor. When I create mock for this class then function is called from constructor. I want to block function calling. Can I do it?
Sample code:
public class Foo
{
public Foo()
{
Initialize();
}
private void Initialize()
{
//some code
}
}
[TestFixture]
public class Test
{
[Test]
public void Test_Foo()
{
Foo foo = MockRepository.GenerateMock<Foo>();
//some test
}
}
Notes:
I don't want to add interface, like Foo : IFoo.
I don't want to add second constructor.
When you are mocking a class, there is proxy created (Rhino uses Castle.DynamicProxy.DefaultProxyBuilder), which inherits from your class. And inheritance works exactly like anywhere in C#. When you create instance of derived type, all constructors of base types (up to object) are invoked.
So, when instance of proxy is created (via Activator.CreateInstance(typeof(proxy))), constructor of Foo also will be invoked. You can't avoid this. You can use interface mocking, or provide some parameter to constructor which will disable initializing.
BTW mocking abstract or concrete class kills all advantages of mocks - your tests becomes dependent on something that is not mocked (constructors, non-virtual methods and default implementations). And your SUT (system under test) is not tested in isolation anymore. Broken test could be result of some changes inside abstract or concrete class.
In general you can create mocks of interfaces or abstract classes only.
What are you going to test? If it is the class Foo then creating a mock of it is completely wrong.
Usually you create mocks of those dependencincies of your tested class that are hard to set up or take long to run. Most common example of such dependency is a repository or a web-service.
How abt adding a Boolean flag
Boolean flag = false;
[Test]
public void Test_Foo()
{
if(flag == true)
{
Foo foo = MockRepository.GenerateMock<Foo>();
}
//some test
}

Moq requirements? Defeats the purpose?

Doesn't being required to virtualize all property accessors you want to mock kind of defeat the purpose of mocking?
I mean, if I have to modify my object and virtualize every single accesor I want to mock, couldn't I just as well inherit my class and mock it myself?
Your question is very valid but if you think about it,there is no other way to mock a class. If you take an interface, it's just a contract so the mock framework can mock how ever you want it but if you take a class, it already has an implementation for it's members.
So the mock framework, in order to be able to mock the class members, has to inherit from the class and override the member's behavior as requested and for this purpose only virtual members will work.
For eg. if you have (I'm showing methods but the same is true for properties)
class Foo
{
public void Bar()
{
}
public virtual void virtualBar()
{
}
}
then the mock framework probably creates something like this to mock
public class MockFoo : Foo
{
public override void virtualBar()
{
// mockery action
}
public new void Bar()
{
// mockery action
}
}
Now when you have
Foo foo = GetMockObject(); // you get an instance of MockFoo
now when you call
foo.Bar();
you don't intend for it to call the actual implementation but since it's a non virtual member, it will call the Foo's Bar()
on the other hand, calling
foo.VirtualBar();
would call MockFoo's VirtualBar() as it's a virtual member which would have the behavior injected by the mock framework as requested.

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