使用模拟数据代替EF进行webapi单元测试



我正在尝试对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

你是正确的,你正在传递一个空列表。

您首先创建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
    _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
    }

然后将列表传递给控制器

相关内容

  • 没有找到相关文章

最新更新