3

I have an interface like this

type IAppDatabase = 
    abstract Get<'T> : seq<Guid> -> Task<seq<'T>>
    abstract Set<'T> : seq<'T> -> Task<bool>
    abstract GetIds<'T> : unit -> Task<seq<Guid>>

I try to mock like this

let results = seq [DT.Result (); DT.Result (); DT.Result ()]
let resultInfos = DT.Results results
let guids = seq [Guid.NewGuid(); Guid.NewGuid(); Guid.NewGuid()]

let taskGetIds = Task.Factory.StartNew<seq<Guid>>(fun () -> guids)
let taskSet = Task.Factory.StartNew<bool>(fun () -> true )
let taskGet = Task.Factory.StartNew<seq<DT.Result>>(fun () -> results)

let db = Mock<IAppDatabase>.With(fun x -> 
            <@  
               x.GetIds () --> taskGetIds
               x.Get guids --> taskGet
               x.Set results --> taskSet @>)

I have a test like this

let [<Test>] ``Set the resultInfos in de app database`` () =
    let app = App (db) :> IApp
    let res = app.Create resultInfos |> Async.RunSynchronously 
    verify <@db.Set results @> once
    res |> should be True

The app.Create function calls the db.Set with an Async.AwaitTask.

This all works well and Foq is great. However the verify raises an system.exception. The methodsMatch function in Foq returns false, because he expectedMethod has a ParameterInfo.ParameterType of System.Collections.Generic.IEnumerable``1[Result] and the actual.Method has a ParameterInfo.ParameterType of System.Collections.Generic.IEnumerable``1[T].

I have tried adding and removing type parameters to no avail. I need the type paramenter (and the Task) in the interface, because it is implemented by someone else in C#.

Is this an issue with the generateAddInvocation method or am I calling the verify wrong?

Remko
  • 754
  • 3
  • 15

1 Answers1

2

This is an issue in the current implementation of Foq 1.1 where verification against generic interface methods fails. The issue is related to the generateAddInvocation method which underneath uses MethodBase.GetCurrentMethod to record each invoked method. MethodBase.GetCurrentMethod returns the generic method definition where as the code quotation used by the verify method receives the type arguments.

I have applied a simple fix: https://foq.codeplex.com/SourceControl/changeset/69435c83aabd

The fix will be part of Foq 1.2.

Phillip Trelford
  • 6,513
  • 25
  • 40