如何使用 FakeItEasy 语法模拟 configuration.GetSection?

How to mock configuration.GetSection with FakeItEasy syntax?

我有以下 appsettings.json 配置。

"SettingsConfig": [
{
  "Name": "Something",
  "Node": "Something",
  "SettingName": "Something"
},
{
  "Name": "Something",
  "Node": "Something",
  "SettingName": "Something"
}]

我想写UnitTest,但是下面的语法不行。

_configuration = A.Fake<IConfiguration>();
A.CallTo(() => _configuration.GetSection("SettingsConfig")).Returns(new List<SettingsConfig>());

错误消息:IConfigurationSection 不包含 Returns 的定义。

如何使用 FakeItEasy 语法模拟 IConfiguration 以便为单元测试应用模拟数据?

首先,您应该实现从文件中读取的方法,该方法存在于单元测试的项目中。因此,如果没有文件 .json 您可以从中读取,您将根本无法使用 GetSection。所以在那里添加文件然后应用:

private IConfiguration ApplyConfiguration()
    {
        var configurationBuilder = new ConfigurationBuilder();
        configurationBuilder.AddJsonFile("settingsConfig.json");
        var config = configurationBuilder.Build();

        config.GetSection("settingsConfig").Get<List<SettingsConfig>>();

        return config;
    }

然后在你的业务逻辑中添加:

var config = ApplyConfiguration();

您会看到 config 包含所有配置,因此根本不需要调用 OnCall .Returns()。

如果您查看 IConfiguration.GetSection() 的 return 值,您会发现它期望 return 和 IConfigurationSection。这是这里的第一个问题。

除此之外,为了从配置中提取您的列表,您需要执行类似

的操作
_configuration.GetSection("SettingsConfig").Get<List<SettingsConfig>>();

不幸的是,IConfigurationSection 上的 .Get<> 方法是一个 扩展方法 ,FakeItEasy 无法伪造它。您将收到以下错误:

The current proxy generator can not intercept the method Microsoft.Extensions.Configuration.ConfigurationBinder.Get... - Extension methods can not be intercepted since they're static.

如果需要测试扩展方法,您需要在 IConfiguration 前面放置另一个接口来包装扩展方法。

否则要伪造您的配置文件,您可以执行以下操作:

var fakeConfigSection = A.Fake<IConfigurationSection>();
A.CallTo(() => fakeConfigSection["Name"])
    .Returns("MyFakedConfigValue");

var fakeConfig = A.Fake<IConfiguration>();
A.CallTo(() => fakeConfig.GetSection("SettingsConfig"))
    .Returns(fakeConfigSection);