This project is read-only.
1

Closed

Mock Call 8 arguments

description

I'm trying to use the Mock<>.Setup().Calls() with a function that has 8 arguments. It seems that the Tuple has a limit of 7 and there is a special case for 7+.

The line Foq.fs#263
let ci = FSharpType.MakeTupleType(args).GetConstructor(args)
works with 7 arguments but when there is 8 it returns null and il.Emit(OpCodes.Newobj, ci) fails.
Closed Jun 14, 2015 at 3:26 PM by ptrelford
Issue fixed in Foq 1.7.1

comments

ptrelford wrote Jun 10, 2015 at 10:50 PM

Thanks for reporting the issue, the source is now updated to support 8+ arguments to the Calls method. I'll push a new Nuget release very soon :)

davidoptima wrote Jun 11, 2015 at 10:26 AM

Thanks for such a quick response and this has fixed the problem on simple 8 argument calls, however I’m hitting I different problem now when trying to use a generic method.

My Code:
type IInterface =
    abstract Arity8Method : string -> string -> string -> string -> DataTable -> 'a seq -> ('a seq -> bool) -> IDictionary<int, int> -> bool

member this.``an implemented interface method with 8 args``() =
    let stub =
        Mock<IInterface>()
            .Setup(fun x -> <@ x.Arity8Method (any()) (any()) (any()) (any()) (any()) (any()) (any()) (any()) @>)
            .Calls<string * string * string * string * DataTable * string seq * (string seq -> bool) * IDictionary<int, int>>(fun (a,b,c,d,e,f,g,h) -> true)
            .Create()
    ignore()
And the error message is:
Result Message: System.NotSupportedException : Illegal one-byte branch at position: 262. Requested branch was: 187.
Result StackTrace:  
at System.Reflection.Emit.ILGenerator.BakeByteArray()
   at System.Reflection.Emit.MethodBuilder.CreateMethodBodyHelper(ILGenerator il)
   at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
   at System.Reflection.Emit.TypeBuilder.CreateType()
   at Foq.Emit.mock(MockMode mode, Type abstractType, FSharpList`1 otherTypes, FSharpList`1 calls, Object[] args, FSharpOption`1 returnStrategy) in C:\xxx\Foq.fs:line 592
   at Foq.Mock`1.Create() in C:\xxx\Foq.fs:line 843
   at Dare.Etl.Transformer.Batching.Tests.BatchingTests.an implemented interface method with 8 args() in C:\xxx\Tests.fs:line 470

ptrelford wrote Jun 11, 2015 at 1:29 PM

Thanks again, there was an issue with many arguments in a generic method, which is now fixed.

I also had to make a small change to your test setup (explicitly specifying the type of the first generic argument):
[<Test>]
let ``an implemented interface method with 8 args``() =
    let stub =
        Mock<IInterface>()
            .Setup(fun x -> <@ x.Arity8Method (any()) (any()) (any()) (any()) (any()) (It.IsAny<string seq>()) (any()) (any()) @>)
            .Calls<string * string * string * string * DataTable * string seq * (string seq -> bool) * IDictionary<int, int>>(fun (a,b,c,d,e,f,g,h) -> true)
            .Create()
    Assert.IsTrue(stub.Arity8Method "1" "2" "3" "4" (new DataTable()) [|"1"|] (fun _ -> true) (dict [1,1]))

davidoptima wrote Jun 12, 2015 at 3:20 PM

Thanks for all your help on this, works great.

ptrelford wrote Jun 14, 2015 at 3:25 PM

No worries, the updates are now available on Nuget as Foq 1.7.1