0

I am using Nunit and FakeItEasy for my MVC Controller functions.

My Test Code:

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

I am getting error at

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

Error: cannot convert lambda expression to type object because it is not a delegate type.

Here is the helper function Code:

public List GetAvailableTypes(Session session,List allTypes,bool includeAllType) { List results = new List(); return results; }

How can i overcome the error.

AMDI
  • 895
  • 2
  • 17
  • 40

2 Answers2

0

If nothing else, your A.CallTo should fail because GetAvailableLicenseTypes isn't virtual. I'm a little surprised at the error message, though. I've tried to reproduce, but had to trim things down quite a bit and fill in missing code, and ended up getting

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

Are you able to include more information, starting with the full error, including stack trace?

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
0

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

These two lines are your issue.

The first line declares nmsFakeHelper as a fake of concrete type NMCHelperFunctions.

The second line then defines the behaviour of the fake when it's GetAvailableLicenseTypes method is called.

In the background, FakeItEasy decides what type of fake it should use (mock, stub, etc.). If the type you are asking a fake of is concrete you get a stub. However, if you want to be able to define behaviour (define return values or validate that methods were called etc.) you need a mock instead of a stub.

To get FakeItEasy to decide to return a mock instead of a stub, you need to give it an interface type instead. This is because a mock needs to be able to intercept the method calls but in .NET, methods can only be intercepted if they are virtual calls. This happens when the type you are using is an interface, but cannot happen when the type you are using is a concrete type.

So to get around this problem, you should add an interface to the NMCHelperFunctions type that includes (at the very least) the GetAvailableLicenseTypes method (as well as any other methods you may).

This means that your first line will change to the following (assuming you name your interface iNMCHelperFunctions): var nmsFakeHelper = A.Fake<iNMCHelperFunctions>(); Your second line would remain unchanged, and your test code should now work.

You may have to refactor your application code to use the interface type instead of the concrete type. There is some benefit from doing this because it allows your components to be swappable so it's easier to add or change behaviour in the future by writing a new class that adheres to the same interface and switching to that.

Geraden
  • 216
  • 1
  • 5