【发布时间】:2014-11-09 18:36:20
【问题描述】:
我有一个提供 GetAll 方法的存储库,该方法再次调用 NHibernate 的 ISession 实例上的 Query 扩展方法。
public ICollection<Product> GetAll()
{
return _session.Query<Product>().ToList();
}
我的单元测试如下所示:
[Test]
public void GetAllReturnsCollectionFromSession()
{
IQueryable<Product> productList = new ProductListBuilder().Build().AsQueryable();
_fixture.Session.Query<Product>().Returns(productList);
var sut = _fixture.CreateSut();
var result = sut.GetAll();
Assert.AreSame(productList, result);
_fixture.Session.Received().Query<Product>();
}
在_fixture.Session.Query().Returns(productList)语句中,NSubstitute抛出如下异常:
NSubstitute.Exceptions.CouldNotSetReturnDueToTypeMismatchException : Can not return value of type IQueryable`1Proxy for ISession.GetSessionImplementation (expected type ISessionImplementor).
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)),
and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member.
Return values cannot be configured for non-virtual/non-abstract members.
Correct use:
mySub.SomeMethod().Returns(returnValue);
Potentially problematic use:
mySub.SomeMethod().Returns(ConfigOtherSub());
Instead try:
var returnValue = ConfigOtherSub();
mySub.SomeMethod().Returns(returnValue);
at NSubstitute.Core.ConfigureCall.CheckResultIsCompatibleWithCall(IReturn valueToReturn, ICallSpecification spec)
at NSubstitute.Core.ConfigureCall.SetResultForLastCall(IReturn valueToReturn, MatchArgs matchArgs)
at NSubstitute.Core.CallRouter.LastCallShouldReturn(IReturn returnValue, MatchArgs matchArgs)
at NSubstitute.Core.SubstitutionContext.LastCallShouldReturn(IReturn value, MatchArgs matchArgs)
at NSubstitute.SubstituteExtensions.Returns[T](MatchArgs matchArgs, T returnThis, T[] returnThese)
at NSubstitute.SubstituteExtensions.ReturnsForAnyArgs[T](T value, T returnThis, T[] returnThese)
at Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests.Repositories.DwapplicationRepositoryTests.GetAllReturnsCollectionFromSession() in C:\git\WELLCOM\source\Statoil.Wellcom.DataLayer.Implementation.Oracle.UnitTests\Repositories\DwapplicationRepositoryTests.cs:line 123
由于 Query 是扩展方法,NSubstitute 似乎无法设置返回值。我将如何模拟 ISession 上的扩展方法调用?
【问题讨论】:
-
您可能不想听到的答案:放弃存储库并使用内存数据库进行测试。见stackoverflow.com/a/12913174/671619
-
关于配置内存数据库以测试 NHibernate 的好文章:ayende.com/blog/3983/nhibernate-unit-testing
标签: nhibernate extension-methods iqueryable nsubstitute