【问题标题】:how to test IQueryable of strongly typed using xUnit in .NET CORE如何在 .NET CORE 中使用 xUnit 测试强类型的 IQueryable
【发布时间】:2021-01-19 09:26:42
【问题描述】:

我正在为 .NET CORE Web API 项目开发一个测试项目。我有 SchoolService 类,它实现了如下一些方法

服务类

 public class SchoolService : ISchoolService
{
    private readonly ISchoolEntity schoolEntity;

    public SchoolService(ISchoolEntity schoolEntity)
    {
        this.schoolEntity = schoolEntity;
    }


    public IQueryable<SchoolDataView> GetAllSchools()
    {
        var query = this.schoolEntity.GetAllSchool();
        return query;
    }

    public SchoolDataView GetSchoolById(Guid Id)
    {
        var query = this.schoolEntity.GetSchoolById(Id);
        return query;
    }

我想测试 1- GetAllSchools 返回对象类型是 IQueryable? 2- 我如何使用 autofix 或通过其他方式让 schoolEntity.GetAllSchool() 返回假的 IQueryable?

服务测试

 public class SchoolServiceTests
{
    private readonly ISchoolService schoolService;
    private readonly ISchoolEntity schoolEntity = Substitute.For<ISchoolEntity>();

    public SchoolServiceTests()
    {
        schoolService = new SchoolService(schoolEntity);
    }

    [Fact]
    public void GetAllSchool_ShouldReturn_IQueryableOfSchoolDataView()
    {
        //Arrange


        //Act
        var a = schoolEntity.GetAllSchool();

        //Assert
        Assert.??
    }
}

【问题讨论】:

  • 您的目标是测试服务实现(SchoolService)吗?那你为什么要在ISchoolEntity中执行GetAllSchool呢?你在这里的期望是什么,你调用了一个总是会返回一个 IQueryable 的假方法。正如我的经验中的一个提示:我一直在使用 Moq 框架,您可以在其中非常轻松地模拟所有接口实现。
  • 谢谢,Martin,我已经回答了我的问题,它给了我一个答案,但希望得到您的反馈和建议,因为我正在测试的主题是 SchoolService 方法,所以这是正确的做法吗?
  • 可能我不明白,但是如果编译器已经测试过了,为什么还要测试GetAllSchool 的返回类型是IQueryable&lt;SchoolDataView&gt;
  • 我认为如果返回类型类似于object 是有道理的,但在你的情况下一切都很清楚,你只能返回实现IQueryable&lt; SchoolDataView &gt; 的类型的对象。为它写测试的原因是什么?

标签: asp.net-web-api .net-core xunit nsubstitute autofixture


【解决方案1】:

我编写了以下测试以实现我在问题中所述的行为。愿意听取更多关于它的反馈和建议。谢谢

    [Fact]
    public void GetAllSchool_ShouldReturn_IQueryableOfSchoolDataView()
    {
        //Arrange
  
        var schoolDataViewList = new List<SchoolDataView>
        {
            new SchoolDataView { SchoolID = Guid.NewGuid(), Name = "London Primary School"},
            new SchoolDataView { SchoolID = Guid.NewGuid(), Name = "Windsor Gramer School"},
            new SchoolDataView { SchoolID = Guid.NewGuid(), Name = "Kings College"},
            new SchoolDataView { SchoolID = Guid.NewGuid(), Name = "Reading School"}
        }.AsQueryable();

        schoolEntity.GetAllSchool().Returns(schoolDataViewList);

        //Act
        var actualSchoolList = sut.GetAllSchools();

        //Assert
        Assert.IsAssignableFrom<IQueryable<SchoolDataView>>(actualSchoolList);
    }

或使用自动夹具

 [Fact]
    public void GetAllSchool_ShouldReturn_IQueryableOfSchoolDataView()
    {
        //Arrange
        var fixture = new Fixture();

        var schoolDataViewMock = fixture.CreateMany<SchoolDataView>();
       
        schoolEntity.GetAllSchool().Returns(schoolDataViewMock.AsQueryable());

        //Act
        var actualSchoolDataList = sut.GetAllSchools();

        //Assert
        Assert.IsAssignableFrom<IQueryable<SchoolDataView>>(actualSchoolDataList);
    }

【讨论】:

  • 我喜欢对上述方法的反馈
  • 你的测试什么时候会失败(我的意思是红线,不是编译错误)?对我来说似乎永远不会,可能只有当actualSchoolDataListnull 时,但在这种情况下,我会根据null 而不是返回类型来测试结果。
猜你喜欢
  • 2020-09-27
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 2018-05-16
  • 2017-08-24
  • 2018-02-20
  • 2018-05-26
  • 1970-01-01
相关资源
最近更新 更多