【问题标题】:using mock data instead of EF for webapi unit test使用模拟数据而不是 EF 进行 webapi 单元测试
【发布时间】:2014-08-19 09:04:04
【问题描述】:

我正在尝试零快乐地对 webapi 项目进行单元测试。

api 使用 EF6.1 访问数据。我的测试项目正在使用 moq 和 xunit。

我已经设置了一个基本测试,比如

    [Fact]
    public void CheckGroupedDataCountEquals2()
    {

        var mockData = new List<Skill>()
        {
            new Skill() {Id = 1, Name = ".net"},
            new Skill() {Id = 2, Name = "asp.net", ParentId = 1},
            new Skill() {Id = 3, Name = "c#", ParentId = 1},
            new Skill() {Id = 4, Name = "php"},
            new Skill() {Id = 5, Name = "zend", ParentId = 4},
            new Skill() {Id = 6, Name = "zend3", ParentId = 5}
        };

        // Arrange
        _skillMock.Setup(x => x.GroupedSkills())
            .Returns((new List<GroupedSkill>()));

        var controller = new SkillsController(_skillMock.Object);

        // Act
        IHttpActionResult actionResult = controller.Get();
        var contentResult = actionResult as OkNegotiatedContentResult<List<GroupedSkill>>;

        // Assert
        Assert.NotNull(contentResult);


        var result = contentResult.Content as List<GroupedSkill>;
        Assert.Equal(2,result.Count);

    }

我的 apicontroller 操作看起来像

    [HttpGet]
    [Route("")]
    // GET api/<controller>
    public IHttpActionResult Get()
    {

        var data = _skillRepository.GroupedSkills();
        if (data!=null)
        {
            return Ok(data);
        }
        return NotFound();
    }

最后......我的回购

    public List<GroupedSkill> GroupedSkills()
    {
        using (var context = new DataContext())
        {
            var data = context.Skills.ToList();

            var newList = data.Where(x => x.ParentId != null).ToList().GroupBy(x => x.ParentId,
                        (key, elements) =>
                           new
                           {
                               data.First(i => i.Id == key).Name,
                               GroupId = key,
                               Skills = elements.ToList()
                           })
               .ToList();

            var filtered = new List<GroupedSkill>();
            foreach (var item in newList)
            {
                filtered.Add(new GroupedSkill()
                {
                    GroupId = item.GroupId.Value,
                    Name = item.Name,
                    Skills = item.Skills
                });
            }
            return filtered;
        }
    }

我的测试总是失败,组数总是 0。我认为这是因为我没有添加 mockData 的模拟列表,而我的存储库对此一无所知.....我说的对吗?如何将我的模拟数据列表从我的测试传递到 repo

【问题讨论】:

    标签: asp.net-web-api moq xunit


    【解决方案1】:

    你是对的,你传递的是一个空列表。

    您首先创建了mockedData 列表,并用真正的Skills 填充它,但您似乎从未使用过它。 这也应该被认为是安排部分的一部分,因为这是值得的。

        var mockData = new List<Skill>()
        {
            new Skill() {Id = 1, Name = ".net"},
            new Skill() {Id = 2, Name = "asp.net", ParentId = 1},
            new Skill() {Id = 3, Name = "c#", ParentId = 1},
            new Skill() {Id = 4, Name = "php"},
            new Skill() {Id = 5, Name = "zend", ParentId = 4},
            new Skill() {Id = 6, Name = "zend3", ParentId = 5}
        };
    

    然后,当您通过创建 _skillMock 开始您的 Arrange 部分时,您会创建一个新的空列表。

        // Arrange
        _skillMock.Setup(x => x.GroupedSkills())
            .Returns((new List<GroupedSkill>()));
    

    而且我不知道 _skillMock 是在哪里初始化的;您不应该将它 (并且真的不希望它) 用作类实例变量,因为它可能会在其他测试中发生变化。相反,您应该将该列表设置为类似于您构建 mockData 列表的方式。

    您在这一行中正确地传递了模拟对象:

        var controller = new SkillsController(_skillMock.Object);
    

    但是,由于您没有向该列表添加任何内容,因此该列表将始终为空。

    理想情况下,我认为您想要的是一个真实的列表,其中包含您的 GroupedSkill 对象的模拟,如下所示:

        var mockData = new List<GroupedSkill>()
        {
            new Mock<GroupedSkill>(1, ".net").Object,
            new Mock<GroupedSkill>(2, "asp.net", 1).Object,
            // ... keep going
        }
    

    然后将该列表传递给您的控制器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多