Mikhail Shilkov
Mikhail Shilkov

Reputation: 35134

FsCheck.xUnit: testing types from another assembly

I'm trying to make my first test with FsCheck and xUnit. I have the following setup:

When I run the project (with VS or console runner), I get the following error:

System.Exception : The type Lib.ABC is not handled automatically by FsCheck. 
Consider using another type or writing and registering a generator for it

If I move my type to the Tests assembly, everything works fine (test fails). How do I tests external types?

Upvotes: 2

Views: 645

Answers (2)

TheInnerLight
TheInnerLight

Reputation: 12184

First of all, when I run this, I do get different behaviour to you. An example result from my test project:

Result Message: FsCheck.Xunit.PropertyFailedException : Falsifiable, after 4 tests (0 shrinks) (StdGen (196938613,296107830)): Original: B

This makes sense because fscheck should be capable of automatically creating a generator for a discriminated union type (such as ABC) via reflection, see: https://fscheck.github.io/FsCheck/TestData.html

I would therefore recommend checking all your packages are installed correctly and fully up to date.

I installed:

  • FsCheck (v2.2.4)
  • FsCheck.Xunit (v2.2.4)
  • xunit (v2.1.0)

FSharp.Core

Always be careful when installing nuget packages which reference FSharp.Core as they are often distributed with a specific version which overwrites your project settings.

If this occurs, delete FSharp.Core from your packages.config file, delete the reference to FSharp.Core in your project and replace it with the desired version of FSharp.Core from the list of assemblies. You can find FSharp.Core under extensions.

You can also redirect references to older FSharp.Core versions to a specified newer version using a binding redirect in your app.config file.

Using <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> in your .fsproj can generate such binding redirects automatically. See https://fsharp.github.io/2015/04/18/fsharp-core-notes.html for more details on usage.

Generators

The error message you have refers to a capability fscheck where you can specify how arbitrary instances of your types are created for the purposes of property testing. An example of a custom generator:

type MyGenerators =
    static member ABC() =
        {new Arbitrary<ABC>() with
            override x.Generator = gen { return A; } // generator that creates only A
            override x.Shrinker t = Seq.empty }

I can then use this generator to check my property:

[<Property(Arbitrary=[|typeof<MyGenerators>|])>]
static member ``ABC is always A`` v =
    v = A

This test now always passes because I have always specified that the generator creates an A.

Upvotes: 3

Mikhail Shilkov
Mikhail Shilkov

Reputation: 35134

It appears to be related to a known issue described on FsCheck GitHub.

Basically, FsCheck NuGet package depends on the old version of FSharp.Core library. The old version gets referenced, which makes the test code incompatible to the system under test.

To fix the problem:

  1. After you install FsCheck NuGet package, go to test project references and remove the reference to the old version of FSharp.Core (4.3.1.0 in my case).

  2. Click "Add reference" to add it again, go to Assemblies -> Extensions and add FSharpCore of the same version that is used in your other projects, 4.4.0.0 in my case.

  3. Add an App.config file to your test project with the following contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
            <bindingRedirect oldVersion="4.3.1.0" newVersion="4.4.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>
    </configuration>
    

Upvotes: 4

Related Questions