试图伪造辅助功能时面临问题

时间:2016-06-23 13:58:06

标签: asp.net-mvc-4 nunit fakeiteasy

我正在使用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);

错误: 无法将lambda表达式转换为类型对象,因为它不是委托类型。

这是辅助功能代码:

public List GetAvailableTypes(Session session,List allTypes,bool includeAllType)         {             列出结果= new List();             返回结果;         }

我如何克服错误。

2 个答案:

答案 0 :(得分: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.

您是否能够包含更多信息,从完整错误开始,包括堆栈跟踪?

答案 1 :(得分:0)

var nmsFakeHelper = A.Fake<iNMCHelperFunctions>();

这两行是你的问题。

第一行声明nmsFakeHelper是伪造的具体类型NMCHelperFunctions。

第二行然后在调用GetAvailableLicenseTypes方法时定义伪造的行为。

在后台,FakeItEasy决定应该使用什么类型的假(模拟,存根等)。如果您要求伪造的类型是具体的,那么您将得到一个存根。但是,如果您希望能够定义行为(定义返回值或验证调用方法等),则需要使用mock而不是stub。

要让FakeItEasy决定返回模拟而不是存根,你需要给它一个接口类型。这是因为模拟需要能够拦截方法调用,但在.NET中,方法只能在虚拟调用时被截获。当您使用的类型是接口时会发生这种情况,但是当您使用的类型是具体类型时,则不会发生这种情况。

因此,要解决此问题,您应该为NMCHelperFunctions类型添加一个接口,该接口包含(至少)GetAvailableLicenseTypes方法(以及您可能使用的任何其他方法)。

这意味着您的第一行将更改为以下内容(假设您将接口命名为iNMCHelperFunctions): {{1}} 您的第二行将保持不变,您的测试代码现在应该可以正常工作。

您可能必须重构应用程序代码以使用接口类型而不是具体类型。这样做有一些好处,因为它允许您的组件可以交换,因此通过编写一个符合相同界面并切换到该界面的新类,将来更容易添加或更改行为。