FSpec has just bumbed the version number from 0.0.8 to 0.1.0. There are two important aspects to learn from the version number.
It’s no longer 0.0.x. I believe that the general interface will be more or less stable now.
It’s not 1.0! FSpec is missing some features that you would expect from a mature test framework. E.g. the ability to control which tests to run on a build server. Internally, there is filtering implemented, but it cannot be controlled externally.
This release brings two significant changes:
Some namespaces have changed (but still backwards compatible)
New NuGet package FSpec.AutoFoq that brings easy automocking support using Foq
The main namespace for all of the FSpec library code has changed from FSpec.Core to FSpec.
Matcher code has also been from the namespace MatchersV3 to Matchers.
So the two standard namespaces to open are now FSpec.Dsl and FSpec.Matchers. Assuming that you are not using a different matching framework, e.g. Unquote.
When FSpec reaches a higher level of maturity, I will probably add the AutoOpen attribute to those two modules, making it only necessary to open FSpec.
FSpec should still be backwards compatible though, as functions that “redirect” are implemented in the original namespaces. So hopefully, you should not get any compilation errors, only warnings, after updating FSpec.
FSpec.AutoFoq is a separate NuGet package that adds support for using Foq with an auto-mocking framework. Opening the FSpec.AutoFoq namespace automatically adds extention methods to the TestContext, making it really simple to use.
Usage is best described with this simple and very dumb TestApplicationService.
describe "FSpec.AutoFoq" [ it "allows you to setup code first" <| fun ctx -> let entity = TestEntity.createWithId 42 ctx.InitMock<ITestDataAccess>(fun mock -> mock.Setup(fun x -> <@ x.Load 42 @>) .Returns(entity)) let service = ctx.GetInstance<TestApplicationService>() let entity = service.Get 42 entity.Should (equal entity) it "allows you to inject a configured mock" <| fun ctx -> let entity = TestEntity.createWithId 42 let mock = Mock<ITestDataAccess>() .Setup(fun x -> <@ x.Load 42 @>) .Returns(entity) .Create() ctx.Inject mock let service = ctx.GetInstance<TestApplicationService>() let entity = service.Get 42 entity.Should (equal entity) it "allows you to retrieve the mocked object after execution" <| fun ctx -> let entity = TestEntity.createWithId 42 let service = ctx.GetInstance<TestApplicationService>() service.Save entity let dataAccess = ctx.GetInstance<ITestDataAccess>() verify <@ dataAccess.Save(entity) @> once ]
AutoFoq is based on the NuGet package Ninject.MockingKernel, which is a bit bloated for what should be a really simple task. But I was not in the mood to write yet another automocker at the moment.
If you would like to see similar support for other mocking frameworks, let me know, it’s really easy to extend.