Reputation: 14876
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.
Upvotes: 12
Views: 23885
Reputation: 858
There is no simple way to test it,
The best option is:
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());
}
}
Upvotes: 0
Reputation: 49
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
Upvotes: 1
Reputation: 83356
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());
}
Upvotes: 15