1

When attempting to supply a fake delegate for a method with an optional parameter in a faked object

type MyType () = 
    abstract B: ?s:string -> unit
    default x.B (?s: string) = Option.iter (printfn "Implemented: %s") s

[<Property>]
let doit () = 
    let a = A.Fake<MyType>()
    A.CallTo(fun () -> a.B(ignored())).Invokes(fun s -> Option.iter (printfn "Faked: %s") s)
    a.B "Hello"

FakeItEasy complains

FakeItEasy.Configuration.FakeConfigurationException: Argument constraint is of type System.String, but parameter is of type Microsoft.FSharp.Core.FSharpOption`1[System.String]. No call can match this constraint.

Is there a way to make this run without changing the type definition ?

OrdinaryOrange
  • 2,420
  • 1
  • 16
  • 25
  • There's not quite enough information here to reproduce what you're seeing (at least for me). What is the definition of `ignored` in this example? – Brian Berns Mar 23 '22 at 04:58
  • If I use `A.Ignored` instead of `ignored()`, I get a different error: *An argument constraint, such as That, Ignored, or _, cannot be nested in an argument.* – Brian Berns Mar 23 '22 at 05:13
  • The example is confusing for me because of the 2 types `A`. Maybe rename your A to MyExample? – Romain Deneau Mar 23 '22 at 06:53
  • Apologies on both fronts. I've updated the question to minimise confusion, and @Brian Berns you had the definition correct. – OrdinaryOrange Mar 23 '22 at 07:59

1 Answers1

2

OK, I was able to reproduce your error message by defining ignored as:

let ignored<'t> () = A<'t>.Ignored

The problem is that you've defined a string constraint for an argument that's actually a string option. You can work around this by explicitly naming the parameter ?s when you call the member, like this:

A.CallTo(fun () -> a.B(?s=ignored())).Invokes(fun s -> Option.iter (printfn "Faked: %s") s)

Now the constraint has the correct type, Option<string>, and the code executes without error. Output is:

Faked: Hello

This SO answer has more details about specifying values for optional arguments.

Brian Berns
  • 15,499
  • 2
  • 30
  • 40