【问题标题】:Facing issue when trying to fake helper function尝试伪造辅助功能时面临的问题
【发布时间】:2016-08-30 00:40:54
【问题描述】:

我将 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(); 返回结果; }

我该如何克服这个错误。

【问题讨论】:

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


    【解决方案1】:

    如果不出意外,您的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.
    

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

    【讨论】:

      【解决方案2】:

      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>(); 您的第二行将保持不变,您的测试代码现在应该可以工作了。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-05
        • 1970-01-01
        • 2018-07-19
        • 1970-01-01
        • 1970-01-01
        • 2015-11-29
        • 1970-01-01
        相关资源
        最近更新 更多