F# 如何设置可以使用 FsUnit 的 FAKE 项目

标签 f# visual-studio-code f#-fake fsunit

我正在尝试设置一个可以运行 FsUnit 的基本 FAKE F# 项目,但我不知道如何解决 Method not found: 'Void FsUnit.TopLevelOperators.should(Microsoft.FSharp.Core.FSharpFunc`2<!!0,!!1>, !!0, System.Object)'错误。

我已经阅读了以下似乎相关的帖子,但显然我仍然没有理解它:

  • Main github issue
  • FSharp.Core packaging guidelines
  • FsUnit unable to test portable library (SO)
  • Another github issue

  • 我创建了一个 JunkTest具有以下设置的库项目:

    包依赖
    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)
    

    build.fsx(相关部分)
    Target "Test" (fun _ ->
        !! (buildDir + "JunkTest.dll")
        |> NUnit3 (fun p ->
            {p with OutputDir = "TestResults" }
        )
    )
    

    输出

    我看到 FSharp.Core.dll 正在从本地复制 packages目录: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".
    而 nunit3-console 执行: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"
    我试图添加一个 app.config在测试项目根目录中添加带有以下内容的文件,但它似乎没有解决问题(注意我没有使用 Visual Studio - 我是否需要为项目做任何特殊的事情来包含 app.config 文件?) :
    <?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>
    

    任何和所有的帮助表示赞赏。

    编辑:解决方案是我没有正确设置 App.config文件以包含在构建中。所有说“只需将它添加到您的 App.config 文件”的答案都没有帮助我,因为 VSCode 没有将它添加到 fsproj自动存档。

    我添加的部分是:
    <None Include="App.config" />
    

    ItemGroup包含另一个 <Compile Include=Foo.fs>线。

    最佳答案

    这是因为 FSharp.Core版本不匹配。看,您的应用程序引用了 FSharp.Core 的一个版本和 FsUnit引用另一个版本。这意味着 FSharpFunc<_,_>对于您和 FsUnit 而言,类型将有所不同(来自不同的程序集) ,这反过来意味着 should FsUnit导出的函数与您的代码正在寻找的函数不同,因为它具有不同类型的参数。

    这是bindingRedirect的地方进来了。您绝对正确地将它添加到 app.config ,但是从您关于您是否正确执行的问题来看,我怀疑您可能没有正确执行。 app.config的事是,它实际上不是程序配置。相反,它是程序配置的源代码。在编译时,这个文件被复制到 bin\Debug\Your.Project.dll.config ,只有这样它才会在运行时被拾取。如果您没有将此文件添加到 fsproj project 文件(我怀疑可能是这种情况),那么它在构建过程中不会被复制到正确的位置,因此不会在运行时被拾取。

    它仍然无法正常工作的另一个原因可能是您指定了不正确的 FSharp.Core 版本。在您的 app.config文件。这让我进入下一点。

    手工制作该文件有点脆弱:升级时 FSharp.Core到新版本(或 Paket 为您完成),您可能忘记在 app.config 中修复它即使你不这样做,也有点麻烦。但是 Paket 可以帮助您:如果您添加 redirects: on options给您的 paket.dependencies文件,Paket 将添加 bindingRedirect cruft 到您的 app.config自动地:

    source https://www.nuget.org/api/v2
    nuget FAKE
    nuget FSharp.Core redirects: on
    nuget FsUnit
    nuget NUnit
    nuget NUnit.Console
    

    关于F# 如何设置可以使用 FsUnit 的 FAKE 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41815649/

    相关文章:

    .net - 在 f# 中使用 Neo4jClient 创建带标签的节点

    linux - 在 IDE 或系统范围内安装框架?

    f# - 无法让 OpenCover 假装工作

    f# - 有没有办法让 F# 保持参数的类型通用?

    list - F#中的列表序列?

    Flutter:将 flavor 配置添加到 Visual Studio

    f#-fake - Paket 依赖组不仅仅是解决版本冲突的一种方法吗?

    Wix 在卸载时删除 appdata 文件夹

    从调试切换到发布时,Silverlight 无法解析引用

    visual-studio-code - VSCode 项目片段在 Windows 上无法按预期工作