最小起订量测试删除方法
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>
接口上的所有方法,但没有告诉模拟版本在调用 Add
或 GetAll
时要做什么。
你需要这样的东西:
_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));
}
此外,我不知道为什么服务处理模型状态(而不是存储库),但您可能应该添加一个额外的断言,说明对象的状态也已正确更新。
我正在尝试为我的服务测试我的删除方法,为此我尝试先向存储库添加一个项目。但是,我认为我的模拟存储库添加方法没有被调用,因为 _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>
接口上的所有方法,但没有告诉模拟版本在调用 Add
或 GetAll
时要做什么。
你需要这样的东西:
_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));
}
此外,我不知道为什么服务处理模型状态(而不是存储库),但您可能应该添加一个额外的断言,说明对象的状态也已正确更新。