我正在尝试测试一种将字典作为参数的方法,通过删除一些不必要的条目对其进行过滤并返回结果字典。我已经单独编写了用于过滤类的测试,这些测试可以正常工作,因此该测试仅与调用过滤器并返回字典有关。
由于某种原因,即使我特别告诉它使用FakeItEasy返回什么,过滤器也会返回空字典。
_callToChartOfAccountsFilterer
断言失败,并显示以下消息:
Assertion failed for the following call: TinyBooks.Services.Json.ChartOfAccounts.IChartOfAccountsFilterer.FilterAccounts(dictionary: Ignored, filteringParameters: Ignored) Expected to find it once exactly but didn't find it among the calls: 1: TinyBooks.Services.Json.ChartOfAccounts.IChartOfAccountsFilterer.FilterAccounts(dictionary: [[Group1, System.Collections.Generic.List`1[TinyBooks.DomainModel.Dtos.AccountForParserDto]]], filteringParameters: TinyBooks.Services.Json.ChartOfAccounts.ChartOfAccountsFilteringParameters)
ChartOfAccountsParser
public class ChartOfAccountsParser : IChartOfAccountsParser
{
private readonly IJsonDeserializer _jsonDeserializer;
private readonly IChartOfAccountsFilterer _chartOfAccountsFilterer;
public ChartOfAccountsParser(IJsonDeserializer jsonDeserializer, IChartOfAccountsFilterer chartOfAccountsFilterer)
{
_jsonDeserializer = jsonDeserializer;
_chartOfAccountsFilterer = chartOfAccountsFilterer;
}
public Dictionary<string, List<AccountForParserDto>> GetChartOfAccountsDictionaryBasedOnJsonFile(
ChartOfAccountsParsingParameters parsingParameters)
{
var filePath = GetPathOfJsonFile(parsingParameters.FileName);
var dictionary = ParseJsonToDictionary(filePath);
var dic = _chartOfAccountsFilterer.FilterAccounts(dictionary, (ChartOfAccountsFilteringParameters)parsingParameters);
return dic;
}
private string GetPathOfJsonFile(string fileName) => Path.Combine(GetFolderOfExecutingAssembly(), "ChartOfAccounts\\Json", fileName);
private string GetFolderOfExecutingAssembly()
=> new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException()).LocalPath;
private Dictionary<string, List<AccountForParserDto>> ParseJsonToDictionary(string filePath)
=> _jsonDeserializer.Load<Dictionary<string, List<AccountForParserDto>>>(filePath);
}
ChartOfAccountsParserTests
[TestFixture]
public class ChartOfAccountsParserTests
{
private IJsonDeserializer _jsonDeserializer;
private IChartOfAccountsFilterer _chartOfAccountsFilterer;
private AccountForParserDto _dto;
private ChartOfAccountsParsingParameters _parameters;
private string _key;
private List<AccountForParserDto> _group;
private Dictionary<string, List<AccountForParserDto>> _dictionary;
private IReturnValueArgumentValidationConfiguration<Dictionary<string, List<AccountForParserDto>>> _callToJsonDeserializer;
private IReturnValueArgumentValidationConfiguration<Dictionary<string, List<AccountForParserDto>>> _callToChartOfAccountsFilterer;
[SetUp]
public void Setup()
{
_jsonDeserializer = A.Fake<IJsonDeserializer>();
_chartOfAccountsFilterer = A.Fake<IChartOfAccountsFilterer>();
_dto = new AccountForParserDto { Name = "Account1" };
_parameters = new ChartOfAccountsParsingParameters { FileName = "a.json" };
_key = "Group1";
_group = new List<AccountForParserDto> { _dto };
_dictionary = new Dictionary<string, List<AccountForParserDto>> { [_key] = _group} ;
_callToJsonDeserializer = A.CallTo(() => _jsonDeserializer.Load<Dictionary<string, List<AccountForParserDto>>>(A<string>._));
_callToChartOfAccountsFilterer = A.CallTo(() => _chartOfAccountsFilterer.FilterAccounts(
A<Dictionary<string, List<AccountForParserDto>>>._,
A<ChartOfAccountsParsingParameters>._));
_callToJsonDeserializer.Returns(_dictionary);
_callToChartOfAccountsFilterer.Returns(_dictionary);
}
[Test]
public void GetChartOfAccountsDictionaryBasedOnJsonFile_GivenDictionaryIgnoringParameters_ReturnsSameDictionary()
{
var parser = new ChartOfAccountsParser(_jsonDeserializer, _chartOfAccountsFilterer);
var result = parser.GetChartOfAccountsDictionaryBasedOnJsonFile(_parameters);
Assert.That(result.ContainsKey(_key));
Assert.That(result.ContainsValue(_group));
_callToJsonDeserializer.MustHaveHappenedOnceExactly();
_callToChartOfAccountsFilterer.MustHaveHappenedOnceExactly();
}
}
答案 0 :(得分:1)
根据您的示例,使用以下支持成员作为概念证明。
public class Parser {
private readonly IFilter filter;
private readonly IProvider provider;
public Parser(IFilter filter, IProvider provider) {
this.filter = filter;
this.provider = provider;
}
public Dictionary<string, List<Dto>> GetData() {
Dictionary<string, List<Dto>> input = provider.Load();
var dictionary = filter.Filter(input);
return dictionary;
}
}
public interface IProvider {
Dictionary<string, List<Dto>> Load();
}
public interface IFilter {
Dictionary<string, List<Dto>> Filter(Dictionary<string, List<Dto>> input);
}
public class Dto {
public string Name { get; set; }
}
以下测试的行为符合预期
[TestClass]
public class DictionaryTests {
[TestMethod]
public void Sohuld_Return_Expected_Data() {
//Arrange
var key = "Group1";
var dto = new Dto { Name = "Account1" };
var group = new List<Dto> { dto };
var dictionary = new Dictionary<string, List<Dto>> {
{ key, group }
};
var provider = A.Fake<IProvider>();
A.CallTo(() => provider.Load()).Returns(dictionary);
var filter = A.Fake<IFilter>();
A.CallTo(() => filter.Filter(A<Dictionary<string, List<Dto>>>._))
.Returns(dictionary);
var subjectUnderTest = new Parser(filter, provider);
//Act
var actual = subjectUnderTest.GetData();
//Assert - using FluentAssertions
actual.ContainsKey(key).Should().BeTrue();
actual.ContainsValue(group).Should().BeTrue();
}
}
答案 1 :(得分:1)
我终于弄清楚了。
问题出在此调用中被忽略参数的类型上
_callToChartOfAccountsFilterer = A.CallTo(() => _chartOfAccountsFilterer.FilterAccounts(
A<Dictionary<string, List<AccountForParserDto>>>._,
A<ChartOfAccountsParsingParameters>._));
不幸的是,我没有显示的是方法签名:
public interface IChartOfAccountsFilterer
{
Dictionary<string, List<AccountForParserDto>> FilterAccounts(
Dictionary<string, List<AccountForParserDto>> dictionary,
IChartOfAccountsFilteringParameters filteringParameters);
}
当我将A<ChartOfAccountsParsingParameters>._
更改为A<IChartOfAccountsFilteringParameters>._
时,测试通过了。