【问题标题】:Mocking a method which inside another method using FakeItEasy使用 FakeItEasy 模拟另一个方法中的方法
【发布时间】:2017-08-25 23:30:25
【问题描述】:

我希望模拟在方法“A”中调用的“B”方法

这是一个例子 在下面的示例中,我希望 MapPath 在被调用时始终返回一些“文本”。

两者属于不同的类别

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 时,它应该总是返回"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
  • 您正在测试方法中创建new ServerPath(),不确定是否可以替换。尝试在您的测试方法中提供虚假实现,而不是 public virtual string Test1(ServerPath IFilePath)TestTest TestClass = new TestTest(FakeServerPath )

标签: c# unit-testing fakeiteasy


【解决方案1】:

您正在手动更新 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 容器注册抽象和实现。

【讨论】:

  • 其实不需要引入接口,直接伪造ServerPath即可
  • @ThomasLevesque 是的,我同意,我明白你的意思。接口抽象是我的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
相关资源
最近更新 更多