fakeiteasyc#-9.0

Delegate does not take 9 arguments (FakeItEasy / C# 9.0)


C# 9.0, FakeItEasy 7.3.1

This is probably just me being dumb, but... Why does FakeItEasy complain that the delegate's parameters don't match??? I've been banged my head against the walls for hours.

public interface IBaseInterface<T> {
      //Not detailed here, for simplification
}

public interface IMyInterface : IBaseInterface<T> {

    public Task<IEnumerable<T>> SearchByCriteriaAsync(
       Guid param0,
       Guid? param1,
       FooClass param2,
       BarClass? param3,
       IEnumerable<Guid> param4, 
       bool param5 = true,
       bool param6 = false,
       bool param7 = true, 
       IReadOnlyCollection<Guid>? param8 = null);
}


internal class MyClass : IMyInterface {
    public Task<IEnumerable<T>> SearchByCriteriaAsync(
       Guid param0,
       Guid? param1,
       FooClass param2,
       BarClass? param3,
       IEnumerable<Guid> param4, 
       bool param5 = true,
       bool param6 = false,
       bool param7 = true, 
       IReadOnlyCollection<Guid>? param8 = null)
    {
        return new List<T>().AsEnumerable();
    }
}

Test class :

        IMyInterface fake = A.Fake<IMyInterface>();


        A.CallTo(() => fake.SearchByCriteriaAsync(
                    A<Guid>.Ignored,
                    A<Guid?>.Ignored,
                    A<FooClass>.Ignored,
                    A<BarClass?>.Ignored,
                    A<IEnumerable<Guid>>.Ignored,
                    A<bool>.Ignored,
                    A<bool>.Ignored,
                    A<bool>.Ignored,
                    A<IReadOnlyCollection<Guid>?>.Ignored
                    ))
                .ReturnsLazily(
                     (
                        Guid param0,
                        Guid? param1,
                        FooClass param2,
                        BarClass? param3,
                        IEnumerable<Guid> param4, 
                        bool param5 = true,
                        bool param6 = false,
                        bool param7 = true, 
                        IReadOnlyCollection<Guid>? param8 = null
                     ) => {
                        return new List<T>().AsEnumerable();
                     }
                );

everything inside the "ReturnsLazily(...)" is highlighted in red, with error message "Error CS1593 Delegate 'Func<IFakeObjectCall, Task<IEnumerable<T>>>' does not take 9 arguments"

if I remove parameter "param0" everywhere, then the compiler stops complaining


Solution

  • FakeItEasy has overloads of ReturnsLazily for up to 8 parameters (it's an arbitrary limit, we could have stopped at 4 or 12, but it seemed a reasonable amount).

    Since you're passing a delegate with 9 parameters, it doesn't match any of the overloads. The compiler assumes (incorrectly) that you're trying to call the overload that accepts a Func<IFakeObjectCall, Task<IEnumerable<T>>>, but the delegate you passed doesn't match that, so it fails.

    The best way to fix this would probably need to refactor your code so that your method doesn't need to take so many parameters. If you can't or don't want to do this, a workaround is to use the overload that works on a IFakeObjectCall:

    ...
    .ReturnsLazily(call => new List<T>().AsEnumerable());
    

    (note that if you need to access the argument values in the delegate, you can use call.GetArgument<Guid>(0), call.GetArgument<FooClass>("param2"), etc.)