How to mock An Abstract Base Class - c#

I have a base class called "Question" and several child classes such as "TrueFalse", "MultipleChoice", "MatchPairs" etc...
The base class has methods with logic that all of the child classes use, such as sending off scores and raising events.
I have set my unit tests up for the child classes but I am not sure how I can setup unit tests for the methods in the base class.
I did some searching and I understand I need to create a Mock of the class but I am not sure how to do this as I have only seen how to do this on an instantiable object.
I have Moq & NUnit installed in project so ideally id like to use this. I am still new to programming and this is my first time adding unit tests so I appreciate any advice you can give me.
I did a search on site first and found a couple of similar questions but they did not give any example on how to do it, just that it needed to be mocked.
Many thanks.

From this answer it looks like what you need is something along these lines:
[Test]
public void MoqTest()
{
var mock = new Moq.Mock<AbstractBaseClass>();
// set the behavior of mocked methods
mock.Setup(abs => abs.Foo()).Returns(5);
// getting an instance of the class
var abstractBaseClass = mock.Object;
// Asseting it actually works :)
Assert.AreEqual(5, abstractBaseClass.Foo());
}

I was trying to mock an abstract class and this way didn't worked for me.
what did work was to create a new class that extended the abstract class
class newclass : abstractClass
{
}
like this I could set the property and test the main method

There is no simple way to test it,
The best option is:
mark base class methods as virtual
create test classes for each of the "TrueFalse", "MultipleChoice", "MatchPairs" classes with virtual methods overridden and invoke public Abstract method.
So for example you have next inheritance structure
class Question {
protected virtual bool CheckCorrect(params int[] answers){
return answers.Any(x => x== 42);
}
}
class TrueFalse: Question {
public int SelectedAnswer {get;set;}
public bool IsCorrect(){
return CheckCorrect(SelectedAnswer );
}
}
class MultipleChoice: Question {
public int[] SelectedAnswers {get;set;}
public bool IsCorrect(){
return CheckCorrect(SelectedAnswers );
}
}
Test methods for this:
abstract class TrueFalseTest: TrueFalseTest{
public abstract bool CheckCorrectReal(params int[] answers);
public override bool CheckCorrect(params int[] answers){
return CheckCorrect(SelectedAnswer );
}
}
abstract class MultipleChoiceTest: MultipleChoice {
public abstract bool CheckCorrectReal(params int[] answers);
public override bool CheckCorrect(params int[] answers){
return CheckCorrect(SelectedAnswer );
}
}
And test methods itself:
class TestQuestionForms{
[Fact]
public void TrueFalseTest_ShouldExecute_CheckCorrectReal()
{
//setup
var mock = new Mock<TrueFalseTest>();
mock.Setup(q => q.CheckCorrectReal(It.IsAny<int[] answers>))
.Returns(true);
//action
mock.Object.IsCorrect();
//assert
mock.Verify(db => db.CheckCorrectReal());
}
[Fact]
public void MultipleChoiceTest_ShouldExecute_CheckCorrectReal()
{
//setup
var mock = new Mock<MultipleChoiceTest>();
mock.Setup(q => q.CheckCorrectReal(It.IsAny<int[] answers>))
.Returns(true);
//action
mock.Object.IsCorrect();
//assert
mock.Verify(db => db.CheckCorrectReal());
}
}

Related

How to test a virtual method defined in an abstract class?

I need to unit-test a virtual method defined in an abstract class. But the base class is abstract, so I can't create an instance of it. What do you recommend me to do?
This is a follow up to the following question: I am thinking about if it is possible to test via an instance of a subclass of the abstract class. Is it a good way? How can I do it?
There's no rule that says a unit test can't define its own classes. This is a fairly common practice (at least for me anyway).
Consider the structure of a standard unit test:
public void TestMethod()
{
// arrange
// act
// assert
}
That "arrange" step can include any reasonable actions (without side-effects outside of the test) which set up what you're trying to test. This can just as easily include creating an instance of a class whose sole purpose is to run the test. For example, something like this:
private class TestSubClass : YourAbstractBase { }
public void TestMethod()
{
// arrange
var testObj = new TestSubClass();
// act
var result = testObj.YourVirtualMethod();
// assert
Assert.AreEqual(123, result);
}
I'm not sure what your abstract class looks like, but if you have something like:
public abstract class SomeClass
{
public abstract bool SomeMethod();
public abstract int SomeOtherMethod();
public virtual int MethodYouWantToTest()
{
// Method body
}
}
And then, as #David suggested in the comments:
public class Test : SomeClass
{
// You don't care about this method - this is just there to make it compile
public override bool SomeMethod()
{
throw new NotImplementedException();
}
// You don't care about this method either
public override int SomeOtherMethod()
{
throw new NotImplementedException();
}
// Do nothing to MethodYouWantToTest
}
Then you just instantiate Test for your unit test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
SomeClass test = new Test();
// Insert whatever value you expect here
Assert.AreEqual(10, test.MethodYouWantToTest());
}
}

C# Unit Testing (Xunit and Moq) - Test an interface and its implementations separately

I want to separate the unit tests for testing the interface behavior itself and the additional business behavior of the implementations.
public interface IIncrementor
{
void Increment();
int Count { get; }
}
public class AIncrementor : IIncrementor { /* Implementation */ }
public class BIncrementor : IIncrementor { /* Implementation */ }
To ensure the correctness of the business behavior of an interface I need to check all according implementations against my defined unit tests. Of course every implementation has its own additional behavior to test, but I don't want to repeat myself over and over again.
My current solution was to create an abstract test-class with an abstract property for the subclasses to implement.
public abstract class IIncrementorTest
{
protected abstract IIncrementor Incrementor { get; }
[Fact]
public void WhenIncremented_ThenCounterHasCorrectValue()
{
var oldCount = Incrementor.Count;
Incrementor.Increment();
Assert.Equal(oldCount + 1, Incrementor.Count);
}
}
public class AIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new AIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
public class BIncremetorTest : IIncrementorTest
{
protected override IIncrementor Incrementor => new BIncrementor();
[Fact]
public void WhenSomeAdditional_ThenCheckSomething() { /* More test */ }
}
But that leads to some problems, e.g. when a test case needs to build an instance differently which is very likely to happen. Would you suggest to create abstract properties for these cases?
protected abstract IIncrementor IncrementorForCheckingSomething { get; }
Or is there a best practice approach which solves this interface-test problem comprehensively?
If I'm understanding correctly, you want to write one set of tests for your interface, and apply those tests to any classes which implement that interface.
You could use reflection to find all the types in your assembly which implement the interface with something like this:
var interfaceType = typeof(IIncrementor);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => t.IsClass && interfaceType.IsAssignableFrom(t));
and instantiate all of those types. This could be tricky if they don't share a common constructor signature; but would work for the examples in the question using the default constructor...
foreach(Type t in types)
{
yield return (IIncrementor)Activator.CreateInstance(t,null);
}
Put that code in a method with return type IEnumerable<IIncrementor> and give that method the attribute MemberData to pass these instances into each of the tests.

Dependency Injection in Unit Tests

I have implemented array based Stack Data Structure along with corresponding Unit Tests. This Stack implements my IStack interface. So at the moment, my UT class looks something like that:
[TestClass]
public class Stack_ArrayBased_Tests
{
//check against empty collection
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new Stack_ArrayBased_Example1(10);
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
Now, I am about to implement Linked List based Stack. This Stack will inherit from the same IStack interface.
I would like to Unit Test the linked list Stack as well. Since both are inheriting from the same interface, I should be able to take advantage of already implemented Unit Test, in order to prevent from unnecessary code duplication.
What would be the best way to create two separate Unit Test classes, one for Array based Stack, and another for Linked List based Stack, that would use the same Unit Test methods? I assume Dependency Injection would be an answer, but how I would go about it?
Dependency injection is never the answer when it comes to tests.
You are not testing abstractions, that's impossible, you test concrete implementations. You can however mock abstractions, interfaces, abstract classes.
You can create some class with the sole purpose of reusing code and you call that class from your test methods, that's ok and totally doable.
You will still need two test classes, one for each of your concrete implementations, and have both call this new class you created. This avoids code duplication.
You can separate logic in another method.
[TestMethod]
public void IsEmpty_NoElements_ArrayBased()
{
var myStack = new Stack_ArrayBased_Example1(10);
IsEmpty_NoElements(myStack)
}
[TestMethod]
public void IsEmpty_NoElements_LinkedListBased()
{
var myStack = new Stack_LinkedListBased_Example1(10);
IsEmpty_NoElements(myStack)
}
public void IsEmpty_NoElements(IStack myStack)
{
var exp = true;
var act = myStack.IsEmpty();
Assert.AreEqual(exp, act);
}
Say we have the following
public interface IStack
{
bool IsEmpty { get; }
}
public class StackImpl1 : IStack
{
public StackImpl1(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
public class StackImpl2 : IStack
{
public StackImpl2(int size)
{
IsEmpty = true;
}
public bool IsEmpty { get; }
}
And we wish to implement the IsEmpty_OnCreation() test from the OP. We can make a common test and add multiple invokers (one for each implementation to be tested). The problem is scaling.
For each new piece of functionality to be tested we need to add
1) the test implementation
2) an invoker for each implementation to be tested.
For each new implementation we introduce, we need to add an invoker for each existing test.
It is possible to use inheritance to do most of the work for us
public abstract class StackTest
{
protected abstract IStack Create(int size);
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = Create(10);
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class StackImp1Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl1(size);
}
}
[TestClass]
public class StackImp2Fixture : StackTest
{
protected override IStack Create(int size)
{
return new StackImpl2(size);
}
}
The tests are generated in each derived fixture.
If we want to add a new test, we add it to the StackTest class and it is automatically included in each derived fixture.
If we add a third implementation of IStack , we simply add a new test fixture deriving from StackTest and overriding the create method.
Note:
If the classes under test have default constructors, the same shape can be used with a Generic StackTest as the base
public class GenStackTest<TStack> where TStack : IStack, new()
{
[TestMethod]
public void IsEmpty_NoElements()
{
var myStack = new TStack();
var exp = true;
var act = myStack.IsEmpty;
Assert.AreEqual(exp, act);
}
}
[TestClass]
public class GenStack1Fixture : GenStackTest<StackImpl1>
{
}
[TestClass]
public class GenStack2Fixture : GenStackTest<StackImpl2>
{
}

moq only one method in a class

I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.

Testing two dependent classes in C#

The problem I want to solve is, how to test two dependent classes in C#. For testing I'm using NUnit and Moq.
Let's say I have a custom collection which autonumerates its items. Values inside collection must be kept in its original order, so that's the reason why it has to be autonumerated. Following code shows the most simple example of mentioned classes:
public interface ICustomItem
{
int Id { get; set; }
ICustomCollection<ICustomItem> ParentCollection { get; set; }
}
public interface ICustomCollection<T> where T : ICustomItem
{
IEnumerable<T> Items { get; set; }
void Add(T t);
// And more of course...
}
public class CustomCollection<T> : ICustomCollection<T> where T : ICustomItem
{
public IEnumerable<T> Items { get; set; }
public void Add(T t)
{
// Some logic here...
t.Id = Items.Count(); // Generate Id
}
}
When adding item to collection, a new Id is generated and assigned to CustomItem. Mechanism of autonumerating should be included also in other methods, such as Remove(), but for this question I've left Add method only.
The question is, how to test if autonumerates works correctly? When the mock is passed as a param, it is not modified inside the class. Should I test the class with simple instance of created-for-tests CustomItem class?
tl;dr
In other words, I want to be able to modify a mock inside a class.
Try to use the class in the test just as you would use it from the production code. This will give you the most usable test in the sense that you are free to refactor the code inside the classes without breaking or even changing a test. The test will also serve as an example on how to use the class.
To start out I would not use Moq, but rather use a short MockCustomItem class that you implement just for the test.
Then use add some values and assert that result is what you expected. Make it a habit to only use one assert in each test like below.
[TestFixture]
public class GivenCustomCollectionWithTwoElements
{
private CustomCollection<MockCustomItem> _customCollection;
[SetUp]
public void SetUp()
{
_customCollection = new CustomCollection<MockCustomItem>();
_customCollection.Add(new MockCustomItem());
_customCollection.Add(new MockCustomItem());
}
[Test]
public void CheckLength()
{
Assert.That(_customCollection.Items, Is.EqualTo(2));
}
[Test]
public void CheckFirstItemId()
{
Assert.That(_customCollection.Items.ElementAt(0).Id, Is.EqualTo(0));
}
[Test]
public void CheckSecondItemId()
{
Assert.That(_customCollection.Items.ElementAt(1).Id, Is.EqualTo(1));
}
private class MockCustomItem : ICustomItem
{
public int Id { get; set; }
public ICustomCollection<ICustomItem> ParentCollection { get; set; }
}
}
Once you get the hang of this, you can also use Moq to create more concise tests with less boilerplate code. In this case NUnit parameterizedtest cases could also be used.
In unit tests you shall only test the unit you are testing right now. So I wold say that you shall mock/fake the ICustomItem and send it in and then looks if the faked object get the Id you expect.
Read my answer here for further info about the same topic Any ASP.NET (WebForm) apps which have good unit tests (CodePlex or anywhere)?
I use FakeItEasy as mock/fake-framework but I guess moq would look pretty similar, here is my code for it
[TestFixture]
public class CustomCollectionTests{
[Test]
public void Add_AddTwoItems_ItemsGetsConsecutiveIds() {
var customItem1 = A.Fake<ICustomItem>();
var customItem2 = A.Fake<ICustomItem>();
var cutomCollection = new CustomCollection<ICustomItem>();
cutomCollection.Add(customItem1);
cutomCollection.Add(customItem2);
Assert.AreEqual(1, customItem1.Id);
Assert.AreEqual(2, customItem2.Id);
}
}
public interface ICustomItem {
int Id { get; set; }
}
public interface ICustomCollection<T> where T : ICustomItem {
void Add(T t);
}
public class CustomCollection<T> : ICustomCollection<T> where T : ICustomItem {
public List<T> innerList = new List<T>();
public void Add(T t) {
// Some logic here...
innerList.Add(t);
t.Id = innerList.Count(); // Generate Id
}
}
Edit
Removed non tested MOQ-example that seemed to be not working.
You're right in the fact that the mock isn't modified. But you should be able to verify the mock after calling the add method like this:
mock.VerifySet(x => x.Id = 42);
Remember to set something in the Items property before calling Add. That something should return 42, when asking for the Count(). That could be a mock as well.

Categories