【问题标题】:F# How to setup FAKE project that can use FsUnitF# 如何设置可以使用 FsUnit 的 FAKE 项目
【发布时间】:2017-01-23 21:08:26
【问题描述】:

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

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

我使用以下设置创建了一个 JunkTest 库项目:

paket.dependencies

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

paket.references

FSharp.Core
FsUnit
NUnit

JunkTest.fs

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" />

在包含其他 &lt;Compile Include=Foo.fs&gt; 行的 ItemGroup 中。

【问题讨论】:

  • app.config 文件是否包含在fsproj 文件中?
  • 问题确实出在app.config 文件上——但我在那个“重复”或其他地方找不到的是如何在构建中正确包含app.config 文件。正如我在问题中所述,我使用 Visual Studio,因此需要在 fsproj 中的有关它的信息对我有所帮助。

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


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 你说得对,我没有在fsproj 中正确设置App.config 文件。它现在正在工作 - 尽管我将不得不阅读更多关于 paket 重定向的内容:on。谢谢
【解决方案2】:

这听起来像是 FSharp.Core 版本不匹配。

您使用的 NuGet 包随 FSharp.Core 4.4(不是 4.3.1)一起提供。我建议修改您的绑定重定向以使用 4.4:

<bindingRedirect oldVersion="0.0.0.0-4.3.1.0" newVersion="4.4.0.0" />

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2016-04-04
    相关资源
    最近更新 更多