我正在使用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(); 返回结果; }
我如何克服错误。
答案 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}} 您的第二行将保持不变,您的测试代码现在应该可以正常工作。
您可能必须重构应用程序代码以使用接口类型而不是具体类型。这样做有一些好处,因为它允许您的组件可以交换,因此通过编写一个符合相同界面并切换到该界面的新类,将来更容易添加或更改行为。