Powerful abstract protected method
I have an abstract class:
public abstract class MyClass
{
protected abstract bool IsSavable();
protected bool IsExecutable()
{
//New mode or edit mode
if (ViewMode == ViewMode.New || ViewMode == ViewMode.Edit)
{
return IsSavable();
}
//Search mode
if (ViewMode == ViewMode.Search)
{
return true;
}
return false;
}
}
I would like to unit test this class. So I need to mock the "IsSavable" method. It should always return "true".
I know how to mock my abstract class with Moq. But how can I mock my abstract protected method so that it returns true?
The IsSavable function is called in my abstract class on a specific method (IsExecuteable). I would like to test this method. I know that most of you would recommend testing as in a class that implements "IsSavable". Unfortunately, this will be a lot of classes, and I would like to test my IsExecutable method only once.
source to share
I would like to unit test this class. So I need to mock the "IsSavable" method. It should always return "true".
No, this is non-sequitur. You can simply create a subclass that does what you want:
// Within your test code
class MyClassForTest : MyClass
{
// TODO: Consider making this a property
protected override bool IsSavable()
{
return true;
}
}
Then when you want to run your test, instantiate MyClassForTest
instead MyClass
.
Personally, I prefer to use mocking dependency frameworks rather than the classes I'm testing.
source to share
Just to confirm what @Jon says - the fact that you are trying to Mock a protected method AND call another protected method on an abstract class indicates a smell.
But, by pulling out the heavy artillery - MoqProtected()
extensions and again using direct reflection to actually trigger the SUT IsExecutable
, you can actually do what you want:
// Arrange
var mockMyClass = new Mock<MyClass>();
mockMyClass.Object.ViewMode = ViewMode.New; // I've made an assumption or two here ...
mockMyClass.Protected().Setup<bool>("IsSavable").Returns(true);
// Act!
var result = (bool)mockMyClass.Object.GetType().InvokeMember("IsExecutable",
BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance,
null,
mockMyClass.Object,
null);
// Assert
Assert.IsTrue(result);
mockMyClass.Protected().Verify<bool>("IsSavable", Times.Once());
But I personally would like to revise the constructive and technological ties at this stage.
source to share
The fastest thing to do is to inherit from "MyClass" and override IsSavable.
In a test, it can be a little trickier to distinguish the under test, but that does the trick.
Also, you might think about design - maybe there should be two classes -> one for Saveable behavior and one for unSavable?
source to share