我有一个服务,例如Foo
服务类。
public class FooService : IFooService
{
private readonly IFooRepository _repository;
private readonly ISomeService _eventService;
public FooService(IFooRepository repository, ISomeService eventService)
{
_repository = repository;
_someService = someService;
}
public IReadOnlyCollection<Foo> GetFoos(bool isDeleted = true)
{
var foos= _repository.GetList(x => x.IsDeleted == isDeleted).ToList();
return !foos.Any() ? new List<Foo>(): foos;
}
}
这里是IFooRepository
public interface IFooRepository : IGenericRepository<Foo>
{
}
这是IGenericRepository
public interface IGenericRepository<T> where T: BaseEntity
{
IReadOnlyCollection<T> GetList(Expression<Func<T, bool>> where, params Expression<Func<T, object>>[] nav);
}
在测试中,我想验证FooService的GetFoos
方法是否调用GetList
方法
这是我尝试过的
[TestClass]
public class FooServiceTest
{
private IQueryable<Foo> _foos;
private Mock<IFooRepository> _fooRepository;
private FooService _fooService;
private Mock<ISomeService> _someService;
[TestInitialize]
public void SetUp()
{
_foos = new List<Foo>
{
new Foo
{
EmailId = "a@a.com",
IsDeleted = false,
},
new Foo
{
EmailId = "a@a.com",
IsDeleted = true,
},
}.AsQueryable();
}
[TestMethod]
public void GetGetFoos_CallsGetList()
{
//Arrange
var foos= _foos.Where(x => x.IsDeleted).ToList();
_fooRepository = new Mock<IFooRepository>();
_fooRepository.Setup(m => m.GetList(x => x.IsDeleted)).Returns(foos);
_someServiceMock = new Mock<ISomeService>();
_fooService = new FooService(_fooRepository.Object, _someServiceMock.Object);
//Act
_fooService.GetFoos(true);
//Assert
_fooRepository.Verify(m=>m.GetList(x=>x.IsDeleted), Times.Once());
}
}
但是我在下一行得到参数null异常
var foos= _repository.GetList(x => x.IsDeleted == isDeleted).ToList();
即使在安装过程中我说Returns(foos)
,也仍然会出现这种情况。
我又如何验证接口方法被调用?
答案 0 :(得分:2)
正在发生(很有可能)是,当您执行Expression<Func<T, bool>>
时,Moq无法匹配.Setup()
。
因此,您可以使用IsAny<>()
方法:
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>())).Returns(foos);
如果要断言传入的表达式,请尝试
Expression<Func<Foo, bool>> capturedExpression = null;
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()))
.Returns((Expression<Func<Foo, bool>> e ) => { capturedExpression = e; return foos; });
Assert.IsTrue(capturedExpression.Compile()(_foos[1]));
Assert.IsFalse(capturedExpression.Compile()(_foos[0]));
要验证该方法是否被调用,您还可以将其更改为更多一点:
_fooRepository.Setup(m => m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()))
.Returns((Expression<Func<Foo, bool>> e ) => { capturedExpression = e; return foos; })
.Verifiable();
然后_fooRepository.Verify(m=>m.GetList(It.IsAny<Expression<Func<Foo, bool>>>()), Times.Once());
,但是,如果未调用它,则captureExpression为空(该技术称为隐式断言)