mirror of
https://github.com/Smaug123/WoofWare.Whippet
synced 2025-10-07 00:38:39 +00:00
Some checks are pending
.NET / build (Release) (push) Waiting to run
.NET / analyzers (push) Waiting to run
.NET / build (Debug) (push) Waiting to run
.NET / check-dotnet-format (push) Waiting to run
.NET / check-nix-format (push) Waiting to run
.NET / Check links (push) Waiting to run
.NET / Check flake (push) Waiting to run
.NET / nuget-pack (push) Waiting to run
.NET / expected-pack (push) Blocked by required conditions
.NET / check-accurate-generations (push) Waiting to run
.NET / all-required-checks-complete (push) Blocked by required conditions
.NET / nuget-publish (push) Blocked by required conditions
.NET / nuget-publish-fantomas (push) Blocked by required conditions
.NET / nuget-publish-json-plugin (push) Blocked by required conditions
.NET / nuget-publish-json-attrs (push) Blocked by required conditions
.NET / nuget-publish-argparser-plugin (push) Blocked by required conditions
.NET / nuget-publish-argparser-attrs (push) Blocked by required conditions
.NET / nuget-publish-httpclient-plugin (push) Blocked by required conditions
.NET / nuget-publish-httpclient-attrs (push) Blocked by required conditions
.NET / nuget-publish-interfacemock-plugin (push) Blocked by required conditions
83 lines
2.9 KiB
Markdown
83 lines
2.9 KiB
Markdown
# WoofWare.Whippet.Plugin.InterfaceMock
|
|
|
|
This is a [Whippet](https://github.com/Smaug123/WoofWare.Whippet) plugin for defining mocks for interfaces.
|
|
|
|
It is a copy of the corresponding [Myriad](https://github.com/MoiraeSoftware/myriad) HttpClient plugin in [WoofWare.Myriad](https://github.com/Smaug123/WoofWare.Myriad), taken from commit d59ebdfccb87a06579fb99008a15f58ea8be394e.
|
|
|
|
## Usage
|
|
|
|
Define a file like `Client.fs`:
|
|
|
|
```fsharp
|
|
type IPublicType =
|
|
abstract Mem1 : string * int -> string list
|
|
abstract Mem2 : string -> int
|
|
```
|
|
|
|
In your fsproj:
|
|
|
|
```xml
|
|
<Project>
|
|
<ItemGroup>
|
|
<Compile Include="Client.fs" />
|
|
<Compile Include="GeneratedClient.fs">
|
|
<WhippetFile>Client.fs</WhippetFile>
|
|
<WhippetParamIPublicType>InterfaceMock</WhippetParamIPublicType>
|
|
</Compile>
|
|
</ItemGroup>
|
|
|
|
<ItemGroup>
|
|
<!-- Development dependencies, hence PrivateAssets="all". Note `WhippetPlugin="true"`. -->
|
|
<PackageReference Include="WoofWare.Whippet.Plugin.InterfaceMock" WhippetPlugin="true" Version="" />
|
|
<PackageReference Include="WoofWare.Whippet" Version="" PrivateAssets="all" />
|
|
</ItemGroup>
|
|
</Project>
|
|
```
|
|
|
|
(This plugin follows a standard convention taken by `WoofWare.Whippet.Plugin` plugins,
|
|
where you use Whippet parameters with the same name as each input type,
|
|
whose contents are a `!`-delimited list of the generators which you wish to apply to that input type.)
|
|
|
|
The generator produces a type like this:
|
|
|
|
```fsharp
|
|
/// Mock record type for an interface
|
|
type internal PublicTypeMock =
|
|
{
|
|
Mem1 : string * int -> string list
|
|
Mem2 : string -> int
|
|
}
|
|
|
|
static member Empty : PublicTypeMock =
|
|
{
|
|
Mem1 = (fun x -> raise (System.NotImplementedException "Unimplemented mock function"))
|
|
Mem2 = (fun x -> raise (System.NotImplementedException "Unimplemented mock function"))
|
|
}
|
|
|
|
interface IPublicType with
|
|
member this.Mem1 (arg0, arg1) = this.Mem1 (arg0, arg1)
|
|
member this.Mem2 (arg0) = this.Mem2 (arg0)
|
|
```
|
|
|
|
### What's the point?
|
|
|
|
Reflective mocking libraries like [Foq](https://github.com/fsprojects/Foq) in my experience are a rich source of flaky tests.
|
|
The [Grug-brained developer](https://grugbrain.dev/) would prefer to do this without reflection, and this reduces the rate of strange one-in-ten-thousand "failed to generate IL" errors.
|
|
But since F# does not let you partially update an interface definition, we instead stamp out a record,
|
|
thereby allowing the programmer to use F#'s record-update syntax.
|
|
|
|
### Features
|
|
|
|
You may supply an `isInternal : bool` argument:
|
|
|
|
```xml
|
|
<Compile Include="GeneratedClient.fs">
|
|
<WhippetFile>Client.fs</WhippetFile>
|
|
<WhippetParamIPublicType>InterfaceMock(false)</WhippetParamIPublicType>
|
|
</Compile>
|
|
```
|
|
|
|
By default, we make the resulting record type at most internal (never public),
|
|
since this is intended only to be used in tests;
|
|
but you can instead make it public by setting the `false` boolean.
|