我正在测试一些 Web Api 控制器。但是,我似乎找不到能够将返回值设置为列表的问题是什么。调试时,控制器的输出不会因某些奇怪的原因而被伪造。如果我测试一个仅返回单个值的控制器,那么伪造效果非常好。
控制器是:
public class ClassController : ControllerBase
{
private readonly IClassSqlService ClassSql;
private readonly ILogger<ClassController> Logger;
public ClassController(
IConfiguration config,
ILogger<ClassController> logger,
IDataAccessAbstractFactory<IClassSqlService> classSql)
{
string SMString = config.GetValue<string>(DataAccessName.SMCnx)!;
Logger = logger;
ClassSql = classSql.Create(SMString);
}
[HttpGet]
[ProducesResponseType(200, Type = typeof(List<ClassModel>))]
public async Task<ActionResult<List<ClassModel>>> ReadAllClasses(
string? academic_year = null)
{
List<ClassModel> output;
if(academic_year is not null)
{
bool isIdValid = int.TryParse(academic_year, out int year);
if (isIdValid is false)
return BadRequest();
output = await ClassSql.ReadAllClassesByAcademicYearAsync(academic_year);
}
else
{
output = await ClassSql.ReadAllClassesAsync();
}
if (output.Any() is false)
return NotFound();
return Ok(output);
}
}
我的单元测试如下:
public class ClassControllerTests
{
private readonly IClassSqlService ClassSql;
private readonly ClassController sut;
public ClassControllerTests()
{
var config = A.Fake<IConfiguration>();
var classSql = A.Fake<IDataAccessAbstractFactory<IClassSqlService>>();
var logger = A.Fake<ILogger<ClassController>>();
sut = new ClassController(config, logger, classSql);
ClassSql = classSql.Create(string.Empty);
}
[Fact]
public async Task ReadAllClassesShouldReturnOk()
{
// arrange
var classes = A.CollectionOfFake<ClassModel>(5);
A.CallTo(() => ClassSql.ReadAllClassesAsync()).Returns(classes.ToList());
// action
var result = await sut.ReadAllClasses();
// assert
result.Result.Should().NotBeNull();
result.Result.Should().BeOfType(typeof(OkObjectResult));
result.Value.Should().NotBeEmpty();
}
}
我已阅读 FakeItEasy 的文档,并按照他们的示例伪造集合,但没有成功。
任何帮助都会很棒。
谢谢你。
调试时,控制器的输出不会由于某些奇怪的原因而被伪造
你能解释一下这是什么意思吗?另外,目前还不清楚你会得到什么结果。测试结束时哪些断言失败了?怎么办?
我不确定您的单值和多值返回测试(或生产方法)之间有什么区别,但我会注意一件事。我怀疑是你的问题。
在您的测试代码中,您创建了一个名为
IClassSqlService
的假 ClassSql
(以某种迂回方式,通过在假 Create
上调用 IDataAccessAbstractFactory<IClassSqlService>
)。
在
ClassController
内部,调用classSql.Create(SMString)
来创建一个不同IClassSqlService
,称为ClassSql
。
测试将第一个
ClassSql
配置为返回 classes.ToList()
。控制器调用第二个 ClassSql
,我猜它的 ReadAllClassesAsync
返回一个假的 ClassModel
列表,并且它的行为就像是空的一样。