I am new to using Moq and have not unit tested in about 5 years. Many things have changed.
I'm trying to wrap my head around the basics.
I have an interface.
public interface ILogger
{
void Log(string message)
}
And this interface is implemented in the following way.
public class MyLogger : ILogger
{
public virtual void Log(string message)
{
StaticClass.StaticMethodNotToBeCalled<ILogger>().Log(message);
}
}
I am testing the following logic.
public class MyClass
{
public MyMethod(int z)
{
var logger = new MyLogger();
if(z == 5)
{
logger.Log("it is true");
return true;
}
logger.Log("it is false);
return false;
}
}
My test looks like the following.
[TestMethod]
public void Test_MyMethod()
{
var mock = new Mock<ILogger>();
mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable();
var o = new MyClass();
var result = o.MyMethod(5);
Assert.IsTrue(result);
mock.Verify();
}
The issue I am running into is the static method being called in the implementation of the ILogger interface.
I am guessing I just do not have a good understanding on what exactly a mock should.
What I would like to do is that any time ILogger.Log it is overridden and does not call that static method.
Is this possible?
Am I going about this a wrong way?
You're creating a Mock based on the ILogger
interface, but you are not injecting the Mock into your MyClass
instance. When MyClass
executes it uses an instance of Logger
instead of your ILogger
mock.
Consider something like this for your class instead:
public class MyClass
{
private ILogger logger;
public MyClass(ILogger loggerInstance)
{
logger=loggerInstance;
}
public MyMethod(int z)
{
if(z == 5)
{
logger.Log("it is true");
return true;
}
logger.Log("it is false);
return false;
}
}
Note that in the constructor of MyClass you are now accepting an instance of a class that implements the ILogger
interface. This allows you to inject your mock object in place of the actual concrete Logger:
[TestMethod]
public void Test_MyMethod()
{
var mock = new Mock<ILogger>();
mock.Setup(y => y.Log(It.IsAny<string>()).Verifiable();
var o = new MyClass(mock.Object);
var result = o.MyMethod(5);
Assert.IsTrue(result);
mock.Verify();
}
Dependency injection is the concept that you're missing in your scenario. It is imperative in many cases to writing unit-testable code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With