I'm having difficulties to Mock Microsoft ILogger with Foq.
module MockExample
open Microsoft.Extensions.Logging
open NUnit.Framework
open Foq
//open Foq.Linq
// Implementation
type Worker (logger:ILogger) =
member this.DoSomething (ok:bool) =
if ok then
logger.LogInformation("success 1")
else
logger.LogError("error 1")
// Test file
[<Test>]
let ``When error should log error`` () =
// 1. let logger = Mock<ILogger>().SetupAction(fun lg -> lg.LogError("error")) ...Create() not availabe
// 2.
//let loggerMock = Mock<ILogger>();
//loggerMock.SetupFunc(fun lg -> lg.LogError(It.IsAny<string>())) |> ignore // .Returns() is not usable
//let logger = loggerMock.Create()
let logger = mock()
// act
Worker(logger).DoSomething(false)
verify <@ logger.LogError("error 1") @> once
//verify <@ logger.LogError("success 1") @> never
Test does not pass.
I tried also other syntax to try to "mimic" the LogError signature but withut cuccess.
[EDIT]
As sugegsted I'm trying to mock the real logger method .Log(logLevel, message, ...)
, but still not able to get it working:
Essentially I don't know how to mock this:
member Log<'TState> : logLevel: LogLevel * eventId: EventId * state: 'TState * ``exception`` : exn * formatter: System.Func<'TState,exn,string> -> unit
to extract/register/compare the state
(it contains the log "message").
[Edit 2]
As a workaround, I wrote my mock of the ILogger and it serve the purpose, but my question is still "how to do it with Foq" ?
type LoggerMock () =
let mutable informations:string list = []
let mutable errors:string list = []
member this.LoggedInformations = informations
member this.LoggedErrors = errors
interface ILogger with
member this.Log(logLevel: LogLevel, eventId: EventId, state: 'TState, ``exception``: exn, formatter: System.Func<'TState,exn,string>): unit =
match logLevel with
| LogLevel.Information -> informations <- informations @ [state.ToString()]
| LogLevel.Error -> errors <- errors @ [state.ToString()]
| _ -> ()
member this.BeginScope(state: 'TState): System.IDisposable =
raise (NotImplementedException())
member this.IsEnabled(logLevel: LogLevel): bool =
raise (NotImplementedException())
[<Test>]
let ``When error should log error (custom mock)`` () =
let logger = LoggerMock()
Worker(logger).DoSomething(false)
logger.LoggedErrors |> should contain "error 2"