2

The two tests below fail, of course. But why do the error messages show two identical expected values? Is there a way of only showing one?

myTest returns Expected: <B> or <B> But was: <A>

myTest2 returns Expected: <{ N = 2 }> or <{ N = 2 }> But was: <{ N = 1 }>

This works as expected (e.g. Expected: <B> But was: <A>) when using plain NUnit instead.

This gets pretty nasty when working with more complicated types, of course.

Tests.cs:

namespace Blah

open FsUnit
open NUnit.Framework

module Tests =

    type MyDU = A | B

    type MyRecord = { N: int }

    [<Test>]
    let myTest ()=
        A |> should equal B

    [<Test>]
    let myTest2 ()=
        { N = 1 } |> should equal { N = 2 }

Project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Tests.fs" />
  </ItemGroup>
  
  <ItemGroup>
    <PackageReference Update="FSharp.Core" Version="5.0.2" />
    <PackageReference Include="FsUnit" Version="4.2.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
  </ItemGroup>
  
</Project>
Mark Pattison
  • 2,964
  • 1
  • 22
  • 42
  • I have no experience with FsUnit, but it looks like you're not following the instructions here: https://fsprojects.github.io/FsUnit/ – Bent Tranberg Feb 23 '22 at 15:18
  • @BentTranberg Could you be more specific, please? The only other potential assertion I can see there is `sameAs` which I believe uses reference equality, which is not desired here. – Mark Pattison Feb 23 '22 at 17:58

1 Answers1

1

From looking at the source, it looks like this is the reason:

equal for 'structural equatable' items like records and unions use the NUnit constraint:

Is.EqualTo(x).Or.EqualTo(x).Using<'T>(Equality.Structural)

And this constraint will feed into the error message.

Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • I'm sure I checked that file... anyway, yes that's almost certainly it. – Mark Pattison Feb 23 '22 at 17:13
  • FYI - question edited to ask for a workaround as well as why. – Mark Pattison Feb 23 '22 at 18:19
  • 1
    @MarkPattison I'd guess the workaround is not to use this implementation. So that either means defining your own `equals` or submitting a PR to FsUnit to change it. Perhaps one option is to push the 'either' logic down into the custom comparer `Equality.Structural` (so it returns true if reference-equal *or* structure-equal) and change the constraint to simply `Is.EqualTo(x).Using<'T>(Equality.Structural)`. Though you'd have to check it's not used elsewhere! – Charles Mager Feb 24 '22 at 10:45