3

мне было интересно, если кто-нибудь был подобный пример этого post для FakeItEasy (оригинальный пост here Я пытался найти правильную установку, но не мог получить это право я.. не смог найти никаких примеров в Интернете. Я начинаю преподавать модульное тестирование, и я решил использовать FakeItEasy. Все мои проекты до сих пор используют инфраструктуру сущности и не используют шаблон Repository/UOW, поскольку я считаю DbSet и DbContext достаточно хорошим для моего я понимаю, что есть плюсы и минусы с EF и модульным тестированием, но я все равно хотел бы это понять. Я уверен, что ушел с моей попытки (см. ниже), так как ошибка, которую я получаю, равнаFakeItEasy DbSet/IQueryable <T> - Entity Framework 6

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); 

ответ

7

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

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

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

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

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

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

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

+0

(Добавление интерфейса сработало.) –

+0

Еще раз спасибо за помощь! –