I have a function foo() that in turn calls function bar(). How can I confirm that bar actually gets called?
Example of complex business logic method to test:
class Car
{
IStarter starter
IKeyhole keyhole
IBrakePedal pedal
Drive()
{
keyhole.InsertKey()
keyhole.RotateToStart()
starter.TurnEngineOver()
...
if (pedal.Pressed)
this.SlowDown()
}
}
I have a method that brings together 6 external dependencies (interfaces with methods), and runs them in a sequence, order is not important. I would like to make sure each was called. In another test, I’d like to tweak conditionals and ensure that a subset was called.
In C# with Moq, I have a full page of setup code.
Here’s what I’d like to see in my unit test:
let `check that brake pedal slows down car` =
let car = new Car()
car.pedal.Pressed <- true
car.Drive()
car.SlowDown |> wasCalled
The rest should be inferred from usage. I have a real need to reduce noise in tests.
The closest thing I know to what you want is an AutoMockingContainer.
In a nutshell, it’s an IoC container that gives you a Car with all IStarter, IKeyhole, IBrakepedal stubbed out and wired to the Car instance, without you explicitly registering any of them. You then proceed to set your expectations as usual (in your case, “car.SlowDown() was called”), then call the method under test.
The specifics depend on the IoC container and mocking framework used. The original one was written with Windsor and an old version of Rhino Mocks, but now there are AMC for StructureMap, Ninject, Autofac + Moq, etc.
You could start with one of these and wrap it to make it more idiomatic in F#.
It has its downsides, it’s not something I’d recommend using “by default”.