Unit test to verify that a base class method is called - c#

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

Related

Using NSubstitute is it possible to mock/stub a base class virtual method?

I have an inheritance hierachy that looks something like this;
public abstract class SomeBaseClass
{
public virtual void DoSomething()
{
Console.WriteLine("Don't want this to run");
}
}
public class ConcreteImplementation1 : SomeBaseClass
{
}
public class ConcreteImplementation2 : ConcreteImplementation1
{
public override void DoSomething()
{
Console.WriteLine("This should run");
base.DoSomething();
}
}
Using NSubstitute I would like to stub ConcreteImplementation1's DoSomething() so that only the code in ConcreteImplementation2's DoSomething() method runs with the call to base.DoSomething() doing nothing.
Is this possible and if so how would I do this? Would the code look any different if DoSomething() were async?
Thanks
I don't think this is possible with NSubstitute, or with .NET in general. NSubstitute does support partial mocks, but this is on a per-member basis.
So you can make it call ConcreteImplementation2.DoSomething, but that implementation calls base.DoSomething so that will execute:
var sub = Substitute.For<ConcreteImplementation2>();
sub.When(x => x.DoSomething()).CallBase();
NSubstitute works by implementing/sub-classing a type, so a good rule of thumb is that if you can't do something manually by sub-classing, NSubstitute will not be able to do it either.
In this case, if you create a class ConcreteImplementation3 : ConcreteImplementation2 and override DoSomething, can you call ConcreteImplementation2.DoSomething without it calling SomeBaseClass.DoSomething? In this case I think the answer is no, so NSubstitute will not be able to do this either.

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

Remove coupling and then mock for unit test

This is a dilemma. Say we have two classes
Class A
{
public int memberValue;
}
interface IB
{
int fun();
}
Class B : IB
{
public int fun()
{
var a = new A();
switch(a.memberValue)
{
case 1:
//do something
break;
case 2:
//do something
break;
}
}
}
Now this presents two tightly coupled classes.
For testing B.fun(), we need to mock Class A and provide multiple values for A.memberValue.
As the A object is not required anywhere else beyond the scope of B.fun(), I dont see why should we inject it through B's constructor.
How can we unit test this method fun() ?
Firstly you should probably create an interface for A as well, but if this is just a simple POCO data class, it might be better to just make its properties virtual instead to allow for mocking. You have 3 options I think:
Inject A to the constructor of B if it is a class that will be used often (e.g. a logging class or something). Then you can create a mock version in your test to check how A is used (remember, mocking is for testing behaviour with dependencies).
public class A : IA { ... }
public class B : IB
{
private readonly A a;
public B(IA a)
{
this.a = a;
}
public void Func()
{
//... use this.a ...
}
}
[Test]
public void Func_AHasValue1_DoesAction1()
{
Mock<IA> mock = new Mock<IA>();
mock.Setup(a => a.somevalue).Returns("something");
B sut = new B(mock.Object);
sut.Func();
mock.Verify(m => m.SomethingHappenedToMe());
}
Pass A to the method if it is something that B needs to work with (as it seems here). You can still create a mock version for use in your tests. This is the same code as the above, but mock is passed to the method instead of the constructor. This is the better method if A is some data class generated at runtime instead of a class with behaviour.
Create a factory class for A and inject that into the constructor. Change the method to get A instances from the factory and inject a mock factory in your tests to verify the behaviour.
public class AFactory : IAFactory
{
public IA Create() { ... }
}
public class B : IB
{
private readonly IAfactory factory;
public B(IAFactory factory)
{
this.factory = factory;
}
public void Func()
{
IA a = factory.Create();
//... use this.a ...
}
}
[Test]
public void Func_AHasValue1_DoesAction1()
{
Mock<IAFactory> mockFactory = new Mock<IAFactory>();
Mock<IA> mock = new Mock<IA>();
mockFactory.Setup(f => f.Create()).Returns(mock.Object);
mock.Setup(a => a.somevalue).Returns("something");
B sut = new B(mockFactory.Object);
sut.Func();
mock.Verify(m => m.SomethingHappenedToMe());
}
Option 1 is the standard approach for classes that can be built without any runtime information (e.g. logging classes).
Option 2 is better for when the input is only a data class that is generated at runtime (e.g. a user fills in a form and you have a POCO data class representing the form input).
Option 3 is better when A is something that does have behaviour but can't be created without something generated at runtime.
You'll have to look at your application to see which is most applicable.
Well, you can do it in few ways. Easiest will probably be to create factory method and in tests create class that inherits B and overrides factory method. I think that's something Feathers or Gojko Adzic (I don't really remember in whose book I've read it, i suppose it was Feathers' Working Effectively with Legacy Code) propose in such situations. Sample implementation would be something like:
class B : IB
{
public int fun()
{
A a = this.CreateA();
...
}
protected A CreateA() { return new A(); }
}
and in unit test:
class BTest : B
{
protected override A CreateA() { return mockA(); }
}
This is pretty simple and straightforward solution that does not limit coupling at class level but at least moves different functionalities to different methods so method that does something does not care about object creation.
But you need to carefully think whether it is really what you want. For small, short project it may be fine. For something bigger or long term it may be useful to still refactor code and remove dependency on A from B to make classes less coupled. Also, the pattern you've shown starts to look like Strategy design pattern. Maybe you should not inject A but strategy object that will know how to handle your current situation? That's always thing that comes to my mind when I see if ladder or switch statement.
But it all depends on context and size of your project.

Unit test protected method in C# using Moq

It came to my attention lately that you can unit test abstract base classes using Moq rather than creating a dummy class in test that implements the abstract base class. See How to use moq to test a concrete method in an abstract class? E.g. you can do:
public abstract class MyAbstractClass
{
public virtual void MyMethod()
{
// ...
}
}
[Test]
public void MyMethodTest()
{
// Arrange
Mock<MyAbstractClass> mock = new Mock<MyAbstractClass>() { CallBase = true };
// Act
mock.Object.MyMethod();
// Assert
// ...
}
Now I was wondering if there was a similar technique to allow me to test protected members without having to create a wrapper class. I.e. how do you test this method:
public class MyClassWithProtectedMethod
{
protected void MyProtectedMethod()
{
}
}
I'm aware of the Moq.Protected namespace, however as far as I can see it only allows you to setup expectations with e.g.
mock.Protected().Setup("MyProtectedMethod").Verifiable();
I'm also aware that the obvious answer here is "don't test protected methods, only test public methods", however that's another debate! I just want to know if this is possible using Moq.
Update: below is how I would test this normally:
public class MyClassWithProtectedMethodTester : MyClassWithProtectedMethod
{
public void MyProtectedMethod()
{
base.MyProtectedMethod();
}
}
Thanks in advance.
Another way in Moq to call protected member is the following template:
In your class, with protected member mark your function as virtual.
For example:
public class ClassProtected
{
public string CallingFunction(Customer customer)
{
var firstName = ProtectedFunction(customer.FirstName);
var lastName = ProtectedFunction(customer.LastName);
return string.Format("{0}, {1}", lastName, firstName);
}
protected virtual string ProtectedFunction(string value)
{
return value.Replace("SAP", string.Empty);
}
}
Then in your unit test add reference to
using Moq.Protected;
and in your unit test you can write the following:
[TestFixture]
public class TestClassProttected
{
[Test]
public void all_bad_words_should_be_scrubbed()
{
//Arrange
var mockCustomerNameFormatter = new Mock<ClassProtected>();
mockCustomerNameFormatter.Protected()
.Setup<string>("ProtectedFunction", ItExpr.IsAny<string>())
.Returns("here can be any value")
.Verifiable(); // you should call this function in any case. Without calling next Verify will not give you any benefit at all
//Act
mockCustomerNameFormatter.Object.CallingFunction(new Customer());
//Assert
mockCustomerNameFormatter.Verify();
}
}
Take note of ItExpr. It should be used instead of It. Another gotcha awaits you at Verifiable. I don't know why, but without calling to Verifiable Verify will not be called.
For starters, there's no point in unit testing an abstract method. There's no implementation! You may want to unit test an impure abstract class, verifying that the abstract method was called:
[Test]
public void Do_WhenCalled_CallsMyAbstractMethod()
{
var sutMock = new Mock<MyAbstractClass>() { CallBase = true };
sutMock.Object.Do();
sutMock.Verify(x => x.MyAbstractMethod());
}
public abstract class MyAbstractClass
{
public void Do()
{
MyAbstractMethod();
}
public abstract void MyAbstractMethod();
}
Note that I set CallBase to turn this into a partial mock, in case Do was virtual. Otherwise Moq would have replaced the implementation of the Do method.
Using Protected() you could verify that a protected method was called in a similar manner.
When you create a mock with Moq or another library, the whole point is overriding implementation. Testing a protected method involves exposing existing implementation. That's not what Moq is designed to do. Protected() just gives you access (presumably through reflection, since it's string-based) to override protected members.
Either write a test descendant class with a method that calls your protected method, or use reflection in the unit test to call the protected method.
Or, better yet, don't test protected methods directly.
You've already touched upon the "test the public API, not private" thought process, and you've also already mentioned the technique of inheriting from the class and then testing its protected members that way. Both of these are valid approaches.
Beneath it all, the simple truth is that you consider this implementation detail (as that's what a private or protected member is) important enough to test directly rather than indirectly via the public API that would use it. If it is this important, perhaps it's important enough to promote to its own class. (After all, if it's so important, perhaps it is a responsibility that MyAbstractClass should not have.) The instance of the class would be protected inside MyAbstractClass, so only the base and derived types would have access to the instance, but the class itself would be fully testable otherwise and usable elsewhere if that became a need.
abstract class MyAbstractClass
{
protected ImportantMethodDoer doer;
}
class ImportantMethodDoer
{
public void Do() { }
}
Otherwise, you're left* to the approaches you've already identified.
*Moq may or may not provide some mechanism for getting at private or protected members, I cannot say, as I do not use that particular tool. My answer is more from an architectural standpoint.

Verifying protected abstract methods are called using Moq

Suppose I have the following class:
public class TestBase
{
public bool runMethod1 { get; set; }
public void BaseMethod()
{
if (runMethod1)
ChildMethod1();
else
ChildMethod2();
}
protected abstract void ChildMethod1();
protected abstract void ChildMethod2();
}
I also have the class
public class ChildTest : TestBase
{
protected override void ChildMethod1()
{
//do something
}
protected override void ChildMethod2()
{
//do something completely different
}
}
I'm using Moq, and I'd like to write a test that verifies ChildMethod1() is being called when I call BaseMethod() and runMethod1 is true. Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?
[Test]
public BaseMethod_should_call_correct_child_method()
{
TestBase testBase;
//todo: get a mock of TestBase into testBase variable
testBase.runMethod1 = true;
testBase.BaseMethod();
//todo: verify that ChildMethod1() was called
}
You can also set the expectation/setup as Verifiable and do without a strict mock:
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce()
.Verifiable();
...
//make sure the method was called
testBase.Verify();
Edit
This syntax does not work in current versions of Moq. See this question for how to do it as of at least 4.0.10827
I figured out how to do this. You can can mock protected methods with Moq, and by making a strict mock, you can verify that they were called. Now I can test the base class without having to make any subclasses.
[Test]
public BaseMethod_should_call_correct_child_method()
{
//strict mocks will make sure all expectations are met
var testBaseMock = new Mock<TestBase>(MockBehavior.Strict);
//expect that ChildMethod1() will be called once. (it's protected)
testBaseMock.Protected().Expect("ChildMethod1")
.AtMostOnce();
var testBase = testBaseMock.Object;
testBase.runMethod1 = true;
testBase.BaseMethod();
//make sure the method was called
testBase.VerifyAll();
}
It's a bit of a hack, but how about creating a subclass of TestBase that makes ChildMethod1 and ChildMethod public and then Moqing that?
It seems like your testing the behaviour rather than the public interface. If this is intended then you could probably look at advice for testing private members.
"Is it possible to create an implemention of TestBase with Moq, call BaseMethod() and verify that ChildMethod was called on the Moq implementation?"
It's sort of possible. But then you would be testing the mock object, not the real object.
Two questions that might steer you in the right direction:
Does the descendatn class return a different value than the base class? If so you can test for that and ignore implimentation details (makes refactoring alot easier too).
Does the descendant class call different methods or different dependencies? If so you can check the dependencies.

Categories