2014-09-16 3 views
3

У меня есть репозиторий, предлагающий метод GetAll, который снова вызывает метод расширения запроса на экземпляре ISession NHibernate.NSubstitute бросает CouldNotSetReturnDueToTypeMismatchException при смехотворном запросе на сеансе NHibernate

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() возвращает (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 

Похоже, NSubstitute не может установить возвращаемое значение из-за того, что Query является методом расширения. Как я мог бы высмеивать вызов метода расширения на ISession?

+0

ответа вы, вероятно, не хотите слышать: угробить репозитории и использовать InMemory базы данных для тесты. см. http://stackoverflow.com/a/12913174/671619 – Firo

ответ

1

Самого простое решения является обернуть ISession в другом интерфейсе/конкретном классе, так что вы можете незавершенные, что из:

public interface ISessionWrapper 
{ 
    IQueryable<T> Query<T>(); 
} 

public class SessionWrapper : ISessionWrapper 
{ 
    private readonly ISession _session; 

    public SessionWrapper(ISession session) 
    { 
     _session = session; 
    } 

    public IQueryable<T> Query<T>() 
    { 
     return _session.Query<T>(); 
    } 
}