Moq模拟通用和表达功能

时间:2014-11-29 22:24:07

标签: c# unit-testing generics mocking moq

我在尝试模拟委托时遇到了一些问题。到目前为止我所拥有的是:

接口规范:

TResult FindOne<T, TResult>(
    ISpecification<T> criteria, Expression<Func<T, TResult>> property)
    where T : class;

实施规范:

public virtual TResult FindOne<T, TResult>(
    ISpecification<T> criteria, Expression<Func<T, TResult>> property)
    where T : class
{
      return criteria.SatisfyingItemFrom(GetQuery<T>(), property);
}

打电话给我,我正试图嘲笑:

var spec = new MySpecification(Id, s).OrderByDescending(x => x.Code).Take(1);
string LineId = _Repository.FindOne(spec, line => line.Id);

我到目前为止的模拟(不起作用):

_warehouseRepositoryMock
.Setup(x => x.FindOne(It.IsAny<MySpecification>(),
    It.IsAny<Expression<Func<Line, object>>>()))
.Returns(TestLine.Id);

我得到的错误是:

Moq.MockException:IGenericRepository.FindOne(Specification`1 [Line],line =&gt; line.Id)调用因模拟行为Strict而失败。 模拟上的所有调用都必须有相应的设置。

但我不确定如何发送line =&gt; line.Id进入我的模拟。

1 个答案:

答案 0 :(得分:1)

据我所知,It.IsAny<T>()条款必须与声明匹配。

使用

TResult FindOne<T, TResult>(
    ISpecification<T> criteria,
    Expression<Func<T, TResult>> property) where T : class;

使用T as LineTResult as string,它会为您提供相应的

string FindOne(
    ISpecification<Line> criteria,
    Expression<Func<Line, string>> property);

因此设置必须

_warehouseRepositoryMock.Setup(x => x.FindOne(
    It.IsAny<ISpecification<Line>>(),
    It.IsAny<Expression<Func<Line, string>>>())).Returns(TestLine.Id);

如果您想将criteria限制为MySpecification的任何类型或子类型,可以使用It.Is<T>()进行设置:

_warehouseRepositoryMock.Setup(x => x.FindOne(
    It.Is<ISpecification<Line>>(s => s is MySpecification),
    It.IsAny<Expression<Func<Line, string>>>())).Returns(TestLine.Id);