2016-06-23 8 views
0

Я использую Nunit и FakeItEasy для своих функций контроллера MVC.Облицовочная проблема при попытке подделать вспомогательную функцию

Мой Тест Код:

[Test] 
     public async Task Search_Success() 
     { 
      if (!isFakeInitialized) 
       InitializeFake(); 

      url = "/N/UserSvc/v1/Types?skip=0&take=" + Constants.MaxSearchRowNumber; 
      Types= A.CollectionOfFake<Type>(3); 
      List<Type> found=new List<Type>(Types); 
      A.CallTo(() => nFake.GetDataAsync<IEnumerable<Type>>(fakeHttpSession, url)).Returns(Types); 
      var fakeHelper = A.Fake<helperFunctions>(); 
      A.CallTo(() => FakeHelper.GetAvailableTypes(fakeHttpSession, found, true)).Returns(foundTypes); 
      //Act 
      var actionResult = await myController.SearchView(); 
      var viewResult = actionResult as ViewResult; 

      //Assert 
      Assert.IsNotNull(viewResult); 
      Assert.AreEqual("Search", viewResult.ViewName); 
     } 

Я получаю сообщение об ошибке при

A.CallTo(() => nFakeHelper.GetAvailableTypes(fakeHttpSession, found, true)).Returns(foundTypes); 

Ошибка: не может преобразовать лямбда-выражения к типу объекта, поскольку он не является типом делегата.

Вот вспомогательная функция Код:

общественности Список GetAvailableTypes (сессия сессия, Список allTypes, BOOL includeAllType) {Результаты Список = новый список(); результаты возврата; }

Как я могу преодолеть ошибку.

ответ

0

Если ничего другого, ваш A.CallTo должен потерпеть неудачу, потому что GetAvailableLicenseTypes не virtual. Однако я немного удивлен сообщением об ошибке. Я пытался воспроизвести, но пришлось обрезать вещи вниз совсем немного, и заполнить недостающие код, и в конечном итоге получить

The current proxy generator can not intercept the specified method for the following reason: 
    - Non virtual methods can not be intercepted. 

возможность включать дополнительную информацию, начиная с полной ошибки, в том числе стек Вы проследить?

0

var nmsFakeHelper = A.Fake<NMCHelperFunctions>(); A.CallTo(() => nmsFakeHelper.GetAvailableLicenseTypes(fakeHttpSession, foundLicense, true)).Returns(foundLicensTypes);

Эти две линии ваш вопрос.

Первая строка объявляет nmsFakeHelper как подделку конкретного типа NMCHelperFunctions.

Вторая строка определяет поведение подделки при вызове метода GetAvailableLicenseTypes.

На заднем плане FakeItEasy решает, какой тип подделки он должен использовать (макет, заглушка и т. Д.). Если тип, который вы задаете подделку, конкретный, вы получаете заглушку. Однако, если вы хотите иметь возможность определять поведение (определять возвращаемые значения или проверять, какие методы были вызваны и т. Д.), Вам нужен макет вместо заглушки.

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

Чтобы обойти эту проблему, вы должны добавить интерфейс к типу NMCHelperFunctions, который включает (по крайней мере) метод GetAvailableLicenseTypes (а также любые другие методы, которые вы можете).

Это означает, что первая строка изменится следующим образом (предполагается, что вы называете ваш интерфейс iNMCHelperFunctions): var nmsFakeHelper = A.Fake<iNMCHelperFunctions>(); Ваша вторая линия останется без изменений, и ваш тестовый код должен теперь работать.

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