0

I'm learning F# recently. Today I wrote some code and tried to add unit tests.

I planed to create two projects, one is for code and the other is for test.

So I created a new solution called DataLab with a project called Source in Visual Studio 2015 Community. Then I added another project called Test.

The structure is like below:

Solution 'DataLab'
    Source
        Queue.fs
    Test
        QueueTest.fs

Queue.fs is:

namespace DataLab

type Queue<'a> = Queue of 'a list * 'a list

module Queue = 
    let init<'a> : Queue<'a> = Queue ([], [])

QueueTest.fs is:

namespace DataLab.Test

module QueueTest =
    open DataLab
    open FsUnit
    open NUnit.Framework

    [<Test>]
    let ``test Init`` () =
        let expected : Queue<int> = Queue ([], [])
        Queue.init<int> |> should equal expected

Then VS warned me about the open statements in QueueTest.fs. One of the three was:

The namespace or module 'FsUnit' is not defined

So I added reference to Source project for Test project. I also installed FsUnit via NuGet for Test project.

I didn't install NUnit because it's a dependency of FsUnit.

And I didn't install FsUnit for Source project because Source does not need testing libraries.
I wanted to make it similar to <scope>test</scope> thing for JUnit dependency in maven.

I built the whole solution successfully.

When I run my test in 'Test Explorer' (I also installed the 'NUnit3 Test Adapter' extension), I got error below:

System.MissingMethodException : Method not found: 'DataLab.Queue`1<!0> DataLab.Queue`1.NewQueue(Microsoft.FSharp.Collections.FSharpList`1<!0>, Microsoft.FSharp.Collections.FSharpList`1<!0>)'.

After some random try, I got the test executed successfully by installing FsUnit to Source project too.

I have a theory about this problem.

I installed FsUnit 2.0.0 which has a dependency of FSharp.Core (>= 3.1.2.5). So FSharp.Core 3.1.2.5 has also been installed to my Test project. And this polluted my Test.fsproj file. I have below lines in Test.fsproj:

<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<TargetFSharpCoreVersion>4.4.0.0</TargetFSharpCoreVersion>

<ItemGroup>
  <Reference Include="FSharp.Core">
    <HintPath>..\packages\FSharp.Core.3.1.2.5\lib\net40\FSharp.Core.dll</HintPath>
    <Private>True</Private>
  </Reference>

Meanwhile the Source project still using VS 2015 built-in F#, whose version is 4.0+ . So the two versions of F# conflict.

But I don't know how to prove it or how to fix it.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
kuang
  • 687
  • 1
  • 6
  • 17
  • Start over with a new solution then copy the code into the new projects;you should not have the version problem. I did that when I was checking your code and I did not get the version problem. You should first make the two or three projects, copy in the source code, then for the solution not each project install the code using NuGet. You can right click on the solution and install via NuGet for all the projects at once. Also never manually remove a reference installed by NuGet, only use NuGet to remove the DLL and the reference. Manually removing a reference added by NuGet will cause problems. – Guy Coder Mar 03 '16 at 16:41
  • When I say copy the source I mean to only copy the text and nothing more. Crate the empty fs file first and then paste the source code text into them. If you make a mistake along the way delete the entire solution and start again. – Guy Coder Mar 03 '16 at 16:46

0 Answers0