I have a function that returns Task<bool> (C#).
Task<bool> Update(MemberMarketUpdate memberMarketUpdate);
I'm trying to mock it using Moq (F#).
let verifyUpdate(update:MemberMarketUpdate) =
update.Id |> should equal "market id"
let setup = associationRepository.Setup (fun r -> r.Update(It.IsAny<MemberMarketUpdate>() ))
setup.Callback(fun update -> verifyUpdate update) |> ignore
//setup.Returns(Task.FromResult(True)) <- does not compile
//setup.ReturnsAsync(True) <- does not compile
I'm not able to use ReturnsAsync(True) to mock the Task<bool> result.
The error says:
No overloads match for method ReturnsAsync. The available overloads
are shown below.
(35 overloads here)
What is the correct syntax?
I tried to get your code to type check in a simple F# script file and the only thing I had to do to make it work was to change your upper-case True to lower-case true.
My complete script that type-checks fine, including all the necessary definitions and references looks like this:
#r #"packages\Moq\lib\net45\Moq.dll"
#r #"packages\NUnit\lib\net45\nunit.framework.dll"
#r #"packages\FsUnit\lib\net46\FsUnit.NUnit.dll"
#r #"packages\System.Threading.Tasks.Extensions\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll"
open Moq
open FsUnit
open System.Threading.Tasks
type MemberMarketUpdate =
{ Id: string }
type IAssociationRepository =
abstract Update : MemberMarketUpdate -> Task<bool>
let verifyUpdate(update:MemberMarketUpdate) =
update.Id |> should equal "market id"
let associationRepository = new Mock<IAssociationRepository>();
let setup = associationRepository.Setup (fun r -> r.Update(It.IsAny<MemberMarketUpdate>() ))
setup.Callback(fun update -> verifyUpdate update) |> ignore
setup.Returns(Task.FromResult(true))
setup.ReturnsAsync(true)
I am not that familiar with f# but try it all in one fluent call like the following, if possible.
associationRepository
.Setup(fun r -> r.Update(It.IsAny<MemberMarketUpdate>()))
.Callback(fun update -> verifyUpdate update)
.ReturnsAsync(True) |> ignore
Related
I have module like this
module CommonModule
let addFive x =
x+5
let multiFive x =
x*5
And I would like to list methods of this module by reflection.
I found this: Can you list the contents of a namespace or module in F#, but I don't know how to use it.
I'm new in F#.
Please help
I think the only way to do this is to declare a type inside the module, then use reflection to get the DeclaringType and call GetMethods on that:
open System.Reflection
module CommonModule =
type Marker = interface end
let f x = x * x
typeof<CommonModule.Marker>.DeclaringType.GetMethods()
This will give you a MethodInfo [] containing f and the methods inherited from System.Object:
[|Int32 f(Int32); System.String ToString(); Boolean Equals(System.Object);
Int32 GetHashCode(); System.Type GetType()|]
EDIT (responding to lukaszb's comment)
If you want to look up the module by name, you'll need to get the assembly first, then find the module type within the assembly and call GetMethods. To do this for the previous example, you would add the following code:
// Get the assembly somehow (by name, by GetEntryAssembly, etc)
let assembly = Assembly.GetExecutingAssembly()
// Retrieve the methods (including F# functions) on the module type
let functions =
match assembly.GetTypes() |> Array.tryFind (fun t -> t.Name = "CommonModule") with
| Some moduleType -> moduleType.GetMethods()
| None -> [||]
// Find the function you want
match functions |> Array.tryFind (fun f -> f.Name = "f") with
| Some f -> f.Invoke(null, [|2|]) // Invoke the function
| None -> failwith "Function `f` not found"
One benefit of doing it this way is that you no longer need the Marker type in the module.
This code snippet reproduces a problem I am having with some production code. The function containsProperty represents a real world function that is actually in a library, so that I have no say in what the signature is.
The problem is that I can't figure out how to create a wrapper function that can take a normal function as argument, and then pass that on to containsProperty. I can call containsProperty directly with a function as a lambda expression, but I can't call it with a function that comes from some other source.
The function addToGroup is the best I've come up with so far, and it uses quotations. There are two problems with that approach, which I am trying to figure out. First, how do I get rid of the Func cast in the quotation? Perhaps somehow move it into addToGroup? Second, can I build on this in order to just pass a function? I haven't succeeded in finding something that doesn't produce either a compile time error or a runtime error.
The function addToGroup2 is what I'd like to do, but it doesn't compile. The error message is "No constructors are available for the type 'Quotations.Expr<'a>'".
Why do I bother to struggle with this? Because as long as I can't treat the passed in function as a first class value, I can't create the design I'm after. I want these functions to come along from a collection of records.
If you paste this snippet into LINQPad or something, comment out addToGroup2 and the calls to it, in order to make the snippet compile and run.
open System
open System.ComponentModel
open System.ComponentModel.DataAnnotations // Reference to this assembly required.
type CfgSettings = {
mutable ConnectionString: string
mutable Port: int
}
and CfgSettingsMetadata() =
static member containsProperty<'TProperty>(propertyExpression: Linq.Expressions.Expression<Func<CfgSettings,'TProperty>>) =
Console.WriteLine "good!"
static member addToGroup f =
CfgSettingsMetadata.containsProperty(FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToLambdaExpression f) |> ignore
static member addToGroup2 (f: CfgSettings -> 'TProperty) =
CfgSettingsMetadata.containsProperty(FSharp.Linq.RuntimeHelpers.LeafExpressionConverter.QuotationToLambdaExpression (Quotations.Expr<Func<CfgSettings,'TProperty>>f)) |> ignore
static member BuildMetadata () =
CfgSettingsMetadata.containsProperty(fun x -> x.ConnectionString)
CfgSettingsMetadata.containsProperty(fun x -> x.Port)
CfgSettingsMetadata.addToGroup <# Func<_,_>(fun x -> x.ConnectionString) #>
CfgSettingsMetadata.addToGroup <# Func<_,_>(fun x -> x.Port) #>
CfgSettingsMetadata.addToGroup2 (fun x -> x.ConnectionString)
CfgSettingsMetadata.addToGroup2 (fun x -> x.Port)
CfgSettingsMetadata.BuildMetadata()
Both answers in question Expression<Func<T, bool>> from a F# func helped me somewhat, but I haven't found a solution yet.
So, there are two questions here.
How to pass a function without having to wrap it in <# ... #>?
For this, you just need to add the [<ReflectedDefinition>] attribute to your method's parameter. It implicitly wraps the argument passed to it in a quotation.
type CfgSettingsMetadata() =
static member addToGroup([<ReflectedDefinition>] f: Expr<CfgSettings -> 'TProperty>) =
CfgSettingsMetadata.containsProperty(LeafExpressionConverter.QuotationToLambdaExpression f) |> ignore
// Example use:
CfgSettingsMetadata.addToGroup(Func<_, _>(fun x -> x.ConnectionString))
How to convert from Expr<a -> b> to Expression<Func<a, b>>?
This is indeed explained in the question you linked, although the API has changed a bit since then.
type CfgSettingsMetadata() =
static member addToGroup ([<ReflectedDefinition>] (f: Expr<CfgSettings -> 'TProperty>)) =
let call = LeafExpressionConverter.QuotationToExpression f :?> MethodCallExpression
let lambda = call.Arguments.[0] :?> LambdaExpression
let e = Expression.Lambda<Func<CfgSettings, 'TProperty>>(lambda.Body, lambda.Parameters)
CfgSettingsMetadata.containsProperty(e) |> ignore
// Example use:
CfgSettingsMetadata.addToGroup(fun x -> x.ConnectionString)
Not entirely sure the title describes it ok, but I do have about the following code:
paket.dependencies:
source https://www.nuget.org/api/v2
nuget fsharpx.extras
nuget mongodb.driver
some.fsx:
#r #".\packages\MongoDB.Bson\lib\net45\MongoDB.Bson.dll"
#r #".\packages\MongoDB.Driver\lib\net45\MongoDB.Driver.dll"
#r #".\packages\MongoDB.Driver.Core\lib\net45\MongoDB.Driver.Core.dll"
#r #".\packages\FSharpX.Extras\lib\net45\FSharpX.Extras.dll"
open MongoDB
open MongoDB.Driver
open MongoDB.Bson
open MongoDB.Bson.Serialization
open FSharpx.Choice
let private createClient (connectString:string) = MongoClient(connectString)
let CreateClient = protect createClient
let private getDb name (client:IMongoClient) = client.GetDatabase(name)
let GetDB1 name client =
choose {
let! c = client
return! (protect (getDb name) c)
}
let GetDB2 name (client:Choice<IMongoClient, exn>) =
protect (getDb name)
<!> client
The point for this "excersise" was to write GetDB2 so that it does the same as GetDB1 but use operators (applicatives?), but I am at the moment not able to turn my head to manage this.
The above code compiles, but the signatures for
GetDB1 and GetDB2 are not equal, and Im obviously doing something not right.
val GetDB1 :
name:string ->
client:Choice<#MongoDB.Driver.IMongoClient,exn> ->
Choice<MongoDB.Driver.IMongoDatabase,exn>
val GetDB2 :
name:string ->
client:Choice<MongoDB.Driver.IMongoClient,exn> ->
Choice<Choice<MongoDB.Driver.IMongoDatabase,exn>,exn>
I have tried several versions and orders of doing things in GetDB2 but I more or less always end at same signature as above.
The general idea I initially had was to write small function doing the stuff they should and then add exception handling (protect) and then "wrap" and "unwrap" accordingly.
That might of course not be entirely right idea too.
Are someone able to point me in some directions here for further studies, code examples or anything? Any comments of any type are in fact welcome at this point ;-)
FSharpx doc
Addendum
I think the following should be about same as above, but without the mongodb dependencies.
#r #".\packages\FSharpX.Extras\lib\net45\FSharpX.Extras.dll"
type DataBase =
{
Name: string
}
type Client =
{
connectString: string
} with member this.GetDatabase name = {
Name = name
}
open FSharpx.Choice
let private createClient (connectString:string) = {
connectString= connectString
}
let CreateClient = protect createClient
let private getDb name (client:Client) = client.GetDatabase name
let GetDB1 name client =
choose {
let! c = client
return! (protect (getDb name) c)
}
let GetDB2 name client =
protect (getDb name)
<!> client
You are getting the compounding of types here because you have used the <!> operator, which is map. That is defined something like this:
let map f = function
| Choice1Of2 value = Choice1Of2 (f value)
| Choice2Of2 fail = Choice2Of2 fail
This has the signature ('T -> 'U) -> Choice<'T,'Failure> -> Choice<'U,'Failure>, i.e. the function f is used as a map inside the choice type. For example:
map (sprintf "%d")
has type Choice<int, 'Failure> -> Choice<string, 'Failure>. This is good for applying functions which do not use the Choice type - there is only one possible point of failure, and that happened before the call to map.
Your next function, however, produces a Choice type, but it takes a non-Choice type. This means that you want the errors to propagate through - if there is an error in the value, then choose that. If the value is fine, but there's an error in the function, then use that. If everything is successful, use that. This requires the two error types to be the same, which for you they are (exn).
This is describing the bind operation, defined like this:
let bind f = function
| Choice1Of2 value = f value
| Choice2Of2 fail = Choice2Of2 fail
with signature ('T -> Choice<'U,'Failure>) -> Choice<'T,'Failure> -> Choice<'U,'Failure>.
Note that bind is very similar to map, except that the latter raises the result into a Choice1Of2 - the mapped function is always successful.
In FSharpX, you can access bind by the |>-like operator >>=, or the <|-like operator <<=.
Finally, protect is a fancy way of catching a thrown exception into a Choice2Of2 exn. It is similar to map in that the passed function is of type 'T -> 'U, but the function can also throw an exception and the passed type is not a Choice. protect is defined something like this:
let protect f x =
try
Choice1Of2 (f x)
with
exn -> Choice2Of2 exn
so its signature is ('T -> 'U) -> 'T -> Choice<'U, exn>.
For more information on how everything is implemented, see the source of this computation expression.
Putting this all together, we can see why your example went wrong.
getDb name is a function Client -> DataBase
protect (getDb name) is a function Client -> Choice<DataBase, exn>
map (protect (getDb name)) is therefore a function Choice<Client, exn> -> Choice<Choice<DataBase, exn>, 'Failure>, because map works inside Choice.
What you want, though, is
let GetDB name client =
bind (protect (getDb name)) client
or in operator form,
let GetDB name client = client >>= protect (getDb name)
In general, if your mapping function has signature 'T -> 'U you want map. If it has 'T -> Choice<'U, 'Failure>, you want bind.
I have source from http://sourceforge.net/p/onvifdm/code/HEAD/tree/
When I try to build this solution, I get the following issue in the onvif.utils project.
use! response = request.AsyncGetResponse() |> Async.Map(fun x-> x:?>HttpWebResponse)
Error: Method or object constructor 'Map' not found
D:\Working\onvifdm\onvifdm-code-96-trunk\onvif\onvif.utils\OdmSession.fs
Here's a function that extends Async, taken from a useful source on understanding map.
module Async =
let map f op = async {
let! x = op
let value = f x
return value
}
Which has a type signature ('a -> 'b) -> Async<'a> -> Async<'b>
For example -
let onInts = async { return 1 }
... is an async<int>, and ...
let onStrings = Async.map (fun x -> x.ToString()) onInts
... produces an Async<string>.
You can use following code as a replacement:
let! webResponse = request.AsyncGetResponse()
use response = webResponse:?>HttpWebResponse
Also you can write your own extension to Async type - here is an example how it can be done. All you need is to implement high order function for the code above.
For those still looking for an answer to this, the problem is that Async is referencing the wrong class. Change it to Microsoft.FSharp.Control.Async and the problem should be resolved.
if this is still an open question, let me suggest using FsToolkit.ErrorHandling:
[https://www.nuget.org/packages/FsToolkit.ErrorHandling]
It contains an Async.map implementation and a lot of useful features to deal with Result.
As an alternative I think this should work:
use! response = request.AsyncGetResponse() |> async.Bind (fun x-> x:?>HttpWebResponse |> async.Return)
I am reading Web cloud and mobile solution with F# and I try to follow the web site the author is building. But I have some problem, I am unable to solve. I understand the logic of what I am doing , but it looks like some piece of code is missing to make it work .I have read up to page 19.
I have the following repository module :
module Repository =
let get (source : IQueryable<_>) queryFn=
queryFn |> Seq.toList
let getAll ()=
fun s -> query { for x in s do
select x }
The idea is to use getAll in queryFn to get all items from source. But I have a cast problem between the two .
Here is the controller that makes use of it:
[<HandleError>]
type GuitarsController(context : IDisposable, ?repository ) =
inherit Controller()
let fromRepository =
match repository with
| Some v -> v
| _ -> (context :?> FsMvcAppEntities).guitars
|> Repository.get
new() = new GuitarsController(new FsMvcAppEntities())
member this.Index() =
getAll()
|> fromRepository
|> this.View
getAll() does not go well with |> fromRepository.
The type ''b -> Linq.IQueryable<'c>' is not compatible with the type
'seq<'a>'.
When looking at the type defined in the repository module I can see that queryFn is :
val get : source:IQueryable<'a> -> queryFn:seq<'b> -> 'b list
and the getall gives
unit -> s:System.Linq.IQueryable<'a> -> System.Linq.IQueryable<'a>
Your Repository.get makes no use of source :D.
Change it to:
module Repository =
let get (source : IQueryable<_>) queryFn =
queryFn source |> Seq.toList