FakeItEasy DbSet / IQueryable <T> - Entity Framework 6

dbcontext dbset entity-framework-6 fakeiteasy unit-testing

Вопрос

Мне было интересно, есть ли у кого-нибудь подобный пример для этого сообщения для FakeItEasy (оригинальное сообщение здесь . Я пытался найти правильную настройку, но не мог понять это. Я не мог найти примеры в Интернете. Я начинаю учить я тестировал модульное тестирование, и я решил использовать FakeItEasy. Все мои проекты до сих пор используют инфраструктуру сущности и не используют шаблон репозитория / UOW, так как я считаю DbSet и DbContext достаточно хорошими для своих приложений малого масштаба. Я понимаю, что есть плюсы и минусы с EF и модульное тестирование, но я все равно хотел бы это выяснить. Я уверен, что ушел с моей попытки (см. Ниже), так как ошибка, которую я получаю,

System.NotImplementedException: член «IQueryable.Provider» не был реализован в типе «DbSet 1Proxy' which inherits from 'DbSet 1». Тестовые двойники для «DbSet`1» должны обеспечивать реализацию применяемых методов и свойств.

Любое направление будет очень полезно. Спасибо.

var data = new List<Request> 
{ 
request1, 
request2, 
request3
}.AsQueryable();

var fakeDbSet = A.Fake<DbSet<Request>>();

A.CallTo(() => ((IQueryable<Request>)fakeDbSet).Provider).Returns(data.Provider);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).Expression).Returns(data.Expression);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).ElementType).Returns(data.ElementType);
A.CallTo(() => ((IQueryable<Request>)fakeDbSet).GetEnumerator()).Returns(data.GetEnumerator());

var fakeContext = A.Fake<RequestPortalContext>();
A.CallTo(() => fakeContext.Requests).Returns(fakeDbSet);

var service = new RequestReadService(fakeContext);
var requests = service.GetAllRequests();

Assert.AreEqual(3, requests.Count);
Assert.AreEqual("Test1", requests[0].Name);
Assert.AreEqual("Test2", requests[1].Name);
Assert.AreEqual("Test3", requests[2].Name);

Принятый ответ

Я вообще не знаком с EntityFramework и не могу сказать, что происходит наверняка, поскольку нет следа стека с NotImplementedException, но вот мое предположение:

Вы видите исключение, GetAllRequests либо строкой, определяющей service либо GetAllRequests , а не A.Fake<DbSet<Request>>() .

Это звучит для меня как внутренности RequestReadService (это ваш класс, я не могу найти его в другом месте?) Или что-то, что он вызывает, полагается на DbSet, также реализующий IQueryable.Provider . Теперь. Я не знаю, почему это еще не было. Возможно, это явная реализация, которая отбрасывает его. Лучшее, что я могу предложить (и я не пробовал этого, учитывая мое полное отсутствие знаний EF6), возможно, попытается явно добавить интерфейс к подделке:

A.Fake<DbSet<Request>>(builder => 
                         builder.Implements(typeof (IQueryable<Result>)));

Хотя после того, как я набрал это, я прочитал FakeItEasy вопрос 31 , который, как я опасаюсь, может применяться, и поэтому моя идея может не работать. Опять же, если вы захотите, дайте ему уйти. Это может занять много времени.

В качестве альтернативы, в краткосрочной перспективе я не уверен, что другие обходные пути предложить. Возможно, подделка некоторых интерфейсов, которые DbSet реализует, вместо того, чтобы подделывать сам DbSet ?

Обновлено : после другого вопроса об этом виде и на самом деле захвата EF6, чтобы я мог попробовать, я создал Issue 477 для отслеживания того, что, по-видимому, является основной проблемой здесь.




Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему