F# mock library based on Rhino.Mocks
F# Shell
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
.nuget
Tests
.gitignore
AssemblyInfo.fs
FsMocks.fsproj
FsMocks.nuspec
FsMocks.sln
README.md
Syntax.fs
appveyor.yml
nuget-package.bat
packages.config

README.md

FsMocks / FsharpMocks

F# mock library

FsMocks is an object mocking library written in F#. It is actually a wrapper around Rhino.Mocks 3.6 that simplifies mocking with F#. The API is simple and straightforward because it uses a human-friendly DSL syntax. It can be combined with other test frameworks (NUnit, xUnit, FsUnit, etc.)

Project status

Build status

NuGet

Get the latest package here. This package is compiled against F# 3.0. If you wish to use F# 3.1, download and compile the source code.

Samples

This sample creates a new IList and expects calls to the methods Add() and Clear(), in any order, but with some constraints.

open System.Collections
open FsMocks.Syntax
// create mock object and repository
use mock = new FsMockRepository()   // use the keyword 'let' instead of 'use' if you don't want automatic verification (But why would you want that anyway?)
let mylist1:IList = mock.strict []

// define mock statements
mock.define Unordered {
  ~~ mylist1.Add "e" |> returns 2 |> expected once |> only_if_argument [Is.NotNull()]
  ~~ mylist1.Clear() |> expected twice
}

// run test.
mylist1.Clear()
mylist1.Add("another argument") |> should equal 2  // FsUnit syntax
mylist1.Clear()
// FsMocks will automatically verify expectations at the end of the test. The test will fail if any unexpected call was made

A mock definition can either be Unordered or Ordered. It takes a series of mock statements.

A mock statement begins with ~~, followed by the call or property to mock, followed by mock directives:

// the call is expected twice
~~ o.call() |> expected twice 

// the mock object will return 219 when this expectation is satisfied
~~ o.call("some arg") |> returns 219

// the call is expected only if it respects the given constraints
~~ o.call(arg) |> only_if_argument [Is.NotNull()] 

// Property1 will be implemented as a simple get/set property
~~ o.Property1 |> implement_as_property

// the most powerful statement : the call is manually implemented
let myCustomClearImplementation() = System.Console.WriteLine("list cleared!!!")
~~ list.Clear() |> implement_as (new Action(myCustomClearImplementation))

// throws an exception whenever a method is called
~~ o.call() |> throws (new Exception("Something went wrong!!"))

// subscribe to an event and simulate an event
let b:Button = mock.strict []
let clickRaiser = mock.getEventRaiser(b.Click)
mock.define Ordered {
    b.Click |> subscription expected once
}
b.Click |> Event.add (fun _ -> System.Console.WriteLine "clicked!" )
clickRaiser.Raise(b, new EventArgs()) // this prints "clicked!"

Mock directives can be combined in no particular order, except for the returns directive which must be on the first position.

~~ o.Call(1) |> returns 1 |> only_if_argument [Is.NotNull()] |> expected at_least_once

Mock definitions can be nested:

let [<Fact>] ``1b) 2 Ordered nested in 1 Unordered``() =
    // create mocks
    use mock = new FsMockRepository()
    let list:int IList = mock.strict []
    // mock definition
    mock.define Unordered {
        mock.define Ordered {
            ~~ list.Add(1) |> expected once
            ~~ list.Add(2) |> expected once
        }
        mock.define Ordered {
            ~~ list.Add(3) |> expected twice
            ~~ list.Contains(5) |> returns true |> expected once
        }
    }

    // run test
    list.Add(3)
    list.Add(3)
    Assert.True(list.Contains(5))
    list.Add(1)
    list.Add(2)
    // verify expectations