使用 FakeItEasy 模拟另一个方法内部的方法

Mocking a method which inside another method using FakeItEasy

我想模拟在方法 "A"

中调用的 "B" 方法

这是一个例子 在下面的示例中,我希望 MapPath 总是 return 一些 "text" 每当它被调用时。

两者不同类

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));
    }
}

我想以这样的方式进行模拟,当调用 MapPath 时,它应该总是 returns "test25"(我是否应该实现一个接口?)

我的测试代码:

//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());

您正在手动更新 ServerPath 的实例,它与 TestTest 紧密耦合。这使得模拟它变得更加困难。它应该作为依赖项

注入 TestTest

我建议抽象化依赖关系

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));
    }
}

并使其成为 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;
    }
}

现在您可以模拟它进行测试

//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);

最后,您要确保将抽象和实现注册到组合根中的 DI 容器。