fsprojects / TickSpec

Lean .NET BDD framework with powerful F# integration
Apache License 2.0
133 stars 23 forks source link

Takes only the second value of a tuple #34

Closed jmuukka closed 4 years ago

jmuukka commented 5 years ago

I have following case which did not work as I expected.

module CalculatorStepDefinition

open NUnit.Framework
open TickSpec

let [<Given>] ``I have two numbers`` () =
    3, 5

let [<When>] ``They are added together`` numbers =
    Calculator.add (fst numbers) (snd numbers)

let [<Then>] ``the result is calculated correctly`` (result:int) =
    Assert.AreEqual(3 + 5, result)

module Calculator

let add a b = a + b

The result is 10 and when I debugged I really see that numbers tuple contains 5 and 5.

Expected behavior is to take the tuple and pass it on as tuple with correct values.

michalkovy commented 5 years ago

It is behavior by design. If you return a tuple then it reads it as you returned multiple values and it tries to saves them all (it is needed for more complex examples)

The second number replaces the first because the types are the same (int).

The tuple isn't saved as whole. However, when you ask for a tuple of two ints it is able to construct it because you have an int in the dependency container - so it constructs tuple of two 5.

You can use e.g. record instead.

michalkovy commented 5 years ago

Or, if you want to use tuple, you can "name" it by using a discriminated union:

module CalculatorStepDefinition

open NUnit.Framework
open TickSpec

type D = D of int*int

let [<Given>] ``I have two numbers`` () =
    D (3, 5)

let [<When>] ``They are added together`` (D (f, s)) =
    Calculator.add f s

let [<Then>] ``the result is calculated correctly`` (result:int) =
    Assert.AreEqual(3 + 5, result)