DurableFunctions.FSharp
DurableFunctions.FSharp copied to clipboard
Move to use DurableOrchestrationContextBase to facilitate unit testing via mocks
I was attempting to write some unit tests along the lines of this document
I ran into a problem as its not possible to mock the sealed DurableOrchestrationContext and if I create a mock DurableOrchestrationContextBase its not possible to cast to the concrete type in order to pass to the orchestration workflow
Any objection to me creating a pr to make the change?
Nice, that's interesting! I don't have any predisposition against Base
classes, so give it a try. I'm curious to see what you can come up with. Thanks a ton!
struggling to see how to do this in a non breaking way - thought I could re-define the builder to use #DurableOrchestrationContextBase
which compiles but the orchestration
ce still expects a DurableOrchestrationContext
so inheritance doesn't work as I had hoped
You should probably replace Context
to ContextBase
everywhere, and then you should be good, no?
yeah that was my first attempt and that works but that means function definitions such as this break
[<FunctionName("HelloSequence")>]
let Run ([<OrchestrationTrigger>] context: DurableOrchestrationContext) =
context |>
orchestrator {
let! hello1 = Activity.callByName<string> "SayHello" "Tokyo"
let! hello2 = Activity.callByName<string> "SayHello" "Seattle"
let! hello3 = Activity.callByName<string> "SayHello" "London"
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return [hello1; hello2; hello3]
}
with
error FS0001: Type mismatch. Expecting a 'DurableOrchestra
tionContext -> 'a' but given a 'DurableOrchestrationContextBase -> System.Threading.Tasks.Task<string list>'
The type 'DurableOrchestrationContext' does not match the type 'DurableOrchestrationContextBase'
It would have to change to
[<FunctionName("HelloSequence")>]
let Run ([<OrchestrationTrigger>] context: DurableOrchestrationContextBase) =
context |>
orchestrator {
let! hello1 = Activity.callByName<string> "SayHello" "Tokyo"
let! hello2 = Activity.callByName<string> "SayHello" "Seattle"
let! hello3 = Activity.callByName<string> "SayHello" "London"
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return [hello1; hello2; hello3]
}
so anyone taking the latest version of the library would have to change their code - I was hoping that could be avoided
Ah, thanks for the clarification!
Am I wrong or is it the only example that breaks? If so, I'm fine with this. Honestly, I think this call is awkward anyway, so maybe change it to
let workflow = orchestrator {
let! hello1 = Activity.callByName<string> "SayHello" "Tokyo"
let! hello2 = Activity.callByName<string> "SayHello" "Seattle"
let! hello3 = Activity.callByName<string> "SayHello" "London"
// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
return [hello1; hello2; hello3]
}
Orchestrator.run (workflow, context)
while you are here. This shouldn't require the type change then.