I'm trying to setup a basic FAKE F# project that can run FsUnit but I cannot figure out how to solve the Method not found: 'Void FsUnit.TopLevelOperators.should(Microsoft.FSharp.Core.FSharpFunc`2<!!0,!!1>, !!0, System.Object)'
errors.
I have read the following posts that seem to be related, but I'm apparently still not grokking it:
I have created a JunkTest
library project with the following setup:
source https://www.nuget.org/api/v2
nuget FAKE
nuget FSharp.Core
nuget FsUnit
nuget NUnit
nuget NUnit.Console
FSharp.Core
FsUnit
NUnit
module JunkTest
open FsUnit
open NUnit.Framework
[<Test>]
let ``Example Test`` () =
1 |> should equal 1 // this does not work
//Assert.That(1, Is.EqualTo(1)) // this works (NUnit)
Target "Test" (fun _ ->
!! (buildDir + "JunkTest.dll")
|> NUnit3 (fun p ->
{p with OutputDir = "TestResults" }
)
)
I see that FSharp.Core.dll is being copied from the local packages
directory: Copying file from "c:\Users\dangets\code\exercism\fsharp\dgt\packages\FSharp.Core\lib\net40\FSharp.Core.dll" to "c:\Users\dangets\code\exercism\fsharp\dgt\build\FSharp.Core.dll".
And the nunit3-console execution: c:\Users\dangets\code\exercism\fsharp\dgt\packages\NUnit.ConsoleRunner\tools\nunit3-console.exe "--noheader" "--output=TestResults" "c:\Users\dangets\code\exercism\fsharp\dgt\build\JunkTest.dll"
I have tried to add a app.config
file with the in the test project root directory with the following but it doesn't seem to solve the issue (NOTE I am not using Visual Studio - do I need to do anything special for the project to include the app.config
file?):
<?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="0.0.0.0-4.3.1.0" newVersion="4.3.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Any and all help is appreciated.
EDIT: The solution was that I was not properly setting up the App.config
file to get included in the build. All of the answers that said "just add this to your App.config
file" didn't help me because VSCode doesn't add this to the fsproj
file automatically.
The part that I added is:
<None Include="App.config" />
In the ItemGroup
that contains the other <Compile Include=Foo.fs>
lines.
This happens because of FSharp.Core
version mismatch. See, your application references one version of FSharp.Core
and FsUnit
references another version. This means that the FSharpFunc<_,_>
type is going to be different (coming from different assemblies) for you and FsUnit
, which in turn means that the should
function exported by FsUnit
is not the same function that your code is looking for, because it has a parameter of a different type.
This is where the bindingRedirect
comes in. You're absolutely correctly added it to app.config
, but from your question about whether you're doing it correctly, I get a suspicion that you might not. The thing with app.config
is, it's not actually the program configuration. Rather, it's the source code for program configuration. At compile time, this file gets copied to bin\Debug\Your.Project.dll.config
, and only then it will get picked up at runtime. If you didn't add this file to the fsproj
project file (which, I suspect, might be the case), then it's not getting copied to the right place during build, and thus isn't getting picked up at runtime.
Another reason for it still not working may be that you've specified an incorrect version of FSharp.Core
in your app.config
file. Which brings me to the next point.
Crafting that file by hand is a bit fragile: when you upgrade FSharp.Core
to a new version (or Paket does it for you), you may forget to fix it in app.config
and even if you don't, it's a bit of a hassle. But Paket can help you with that: if you add the redirects: on
options to your paket.dependencies
file, Paket will add the bindingRedirect
cruft to your app.config
automatically:
source https://www.nuget.org/api/v2
nuget FAKE
nuget FSharp.Core redirects: on
nuget FsUnit
nuget NUnit
nuget NUnit.Console
This sounds like an FSharp.Core version mismatch.
The NuGet package you're using ships with FSharp.Core 4.4 (not 4.3.1). I recommend modifying your binding redirect to use 4.4:
<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.4.0.0" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With