最小起订量测试删除方法

Moq testing Delete method

我正在尝试为我的服务测试我的删除方法,为此我尝试先向存储库添加一个项目。但是,我认为我的模拟存储库添加方法没有被调用,因为 _mockRepository.Object.GetAll() 始终为空。我试过使用调试器介入,但它也跳过了它。我做错了什么?

public class CommentServiceTest
{
    private Mock<IRepository<Comment>> _mockRepository;
    private ICommentService _service;
    private ModelStateDictionary _modelState;

    public CommentServiceTest()
    {
        _modelState = new ModelStateDictionary();
        _mockRepository = new Mock<IRepository<Comment>>();
        _service = new CommentService(new ModelStateWrapper(_modelState), _mockRepository.Object);
    }

    [Fact]
    public void Delete()
    {
        var comment = new Comment("BodyText")
        {
            Audio = new Audio(),
            Date = DateTime.Now
        };

        _mockRepository.Object.Add(comment);
        //Nothing in repository collection here still
        var commentToDelete = _mockRepository.Object.GetAll().First();
        _service.Delete(commentToDelete);

        Assert.DoesNotContain(commentToDelete, _mockRepository.Object.GetAll());
    }
}

public class Repository<T, TC> : IRepository<T> where T : class where TC : DbContext
{
    private bool _disposed;

    protected TC Context { get; }

    public Repository()
    {

    }

    public Repository(TC context)
    {
        Context = context;
    }

    public virtual IQueryable<T> GetAll()
    {
        return Context.Set<T>();
    }

    public virtual void Add(T entity)
    {
        Context.Set<T>().Add(entity);
        Save();
    }

    public virtual void Save()
    {
        Context.SaveChanges();
    }   
}

}

您正在模拟 IRepository<T> 接口上的所有方法,但没有告诉模拟版本在调用 AddGetAll 时要做什么。

你需要这样的东西:

_mockRepository
.Setup(r => r.Add(It.IsAny<Comment>()))
.Callback(c => _service.Add(c));

_mockRepository
.Setup(r => r.GetAll())
.Returns(_service.GetAll());

这(或类似的东西)意味着 Add 将内容放入您的列表中,并且 GetAll returns 列表中的内容。

或者,您可以尝试将评论直接添加到 service 而不是添加到存储库中。没有看到服务是如何实现的,我只能猜测它是如何工作的。

您的存储库是一个 mock,因此默认情况下它不包含任何实际行为。您首先必须设置模拟以接受对模拟对象的方法调用。因此,在您的情况下,您首先必须告诉模拟以某种方式处理添加(除了删除之外)。

但是,由于您实际上只是想测试从服务中删除某些内容的服务,因此您不需要先向模拟存储库添加对象。您实际上只需要检查该项目是否已从模拟存储库中正确删除。 IE。由于存储库是模拟的,因此您无需真正添加任何内容即可删除它。

您的测试应如下所示:

[Fact]
public void Delete()
{
    // arrange
    var comment = new Comment("BodyText")
    {
        Audio = new Audio(),
        Date = DateTime.Now
    };

    // set up the repository’s Delete call
    _mockRepository.Setup(r => r.Delete(It.IsAny<Comment>()));

    // act
    _service.Delete(comment);

    // assert
    // verify that the Delete method we set up above was called
    // with the comment as the first argument
    _mockRepository.Verify(r => r.Delete(comment));
}

此外,我不知道为什么服务处理模型状态(而不是存储库),但您可能应该添加一个额外的断言,说明对象的状态也已正确更新。