Reputation: 2832
I wish to mock a "B" method that is called inside the method "A"
Here is an example
In the below example I want MapPath
to always return some "text" whenever it's being called.
Both are in different classes
public class TestTest
{
public virtual string Test1()
{
ServerPath IFilePath = new ServerPath();
string path = IFilePath.MapPath("folder", "filepath");
return path;
}
}
public class ServerPath
{
public virtual string MapPath(string folder, string filepath)
{
Console.WriteLine("ServerPath");
return (System.Web.Hosting.HostingEnvironment.MapPath(folder + filepath));
}
}
I want to mock in such a way that when there is call to MapPath
it should always returns "test25"
(Whether I should implement an interface?)
My TestCode:
//I am using FakeitEasy
TestTest TestClass = new TestTest();
var FakeServerPath = A.Fake<ServerPath>();
var FakeTestTest = A.Fake<TestTest>();
A.CallTo(() => FakeServerPath.MapPath(A<string>.Ignored, A<string>.Ignored)).Returns("test25");
//Should I call FakeTestTest.Test1() or TestClass.Test1() ?
Console.WriteLine(TestClass.Test1());
Upvotes: 3
Views: 1572
Reputation: 246998
You are manually newing up an instance of ServerPath
which tightly couples TestTest
to it. This makes mocking it a little more difficult. It should be injected into TestTest
as a dependency
I would advise abstracting the dependency
public interface IFilePath {
string MapPath(string folder, string filepath);
}
public class ServerPath : IFilePath {
public virtual string MapPath(string folder, string filepath) {
Console.WriteLine("ServerPath");
return (System.Web.Hosting.HostingEnvironment.MapPath(folder + filepath));
}
}
and making it an explicit dependency of TestTest
public class TestTest {
private readonly IFilePath filePath;
public TestTest (IFilePath filePath) {
this.filePath = filePath;
}
public virtual string Test1() {
string path = filePath.MapPath("folder", "filepath");
return path;
}
}
So that now you can mock it for testing
//Arrange
var expected = "test25";
var FakeServerPath = A.Fake<IFilePath>();
A.CallTo(() => FakeServerPath.MapPath(A<string>.Ignored, A<string>.Ignored))
.Returns(expected);
var sut = new TestTest(FakeServerPath);
//Act
var actual = sut.Test1();
//Assert
Assert.AreEqual(expected, actual);
Finally you would make sure to register the abstraction and implementation with the DI container in the composition root.
Upvotes: 4