franela / goblin

Minimal and Beautiful Go testing framework
MIT License
884 stars 79 forks source link

Table driven tests will test only last item #77

Closed viharm91 closed 3 years ago

viharm91 commented 4 years ago

Trying the below code. It should actually fail on first It as it has expected and actual values different.

import (
    "testing"

    . "github.com/franela/goblin"
)

func Test(t *testing.T) {
    g := Goblin(t)
    // RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })
    g.Describe("Holly tessst", func() {
        loopableLoop := []struct {
            expected string
            actual   string
        }{{
            expected: "1",
            actual:   "2",
        },
            {
                expected: "2",
                actual:   "2",
            },
        }

        for _, te := range loopableLoop {
            g.It(te.expected, func() {
                g.Assert(te.expected).Equal(te.actual)
            })
        }
    })
}
sockol commented 4 years ago

For whoever finds this - the "fix" is to define the variables outside of It

        for _, te := range loopableLoop {

            expected := te.expected
            actual := te.actual
            g.It(expected, func() {
                g.Assert(expected).Equal(actual)
            })
        }

Or isolate the context

        for _, te := range loopableLoop {
            func(te struct {
                expected string
                actual   string
            }) {
                g.It(te.expected, func() {
                    g.Assert(te.expected).Equal(te.actual)
                })
            }(te)
        }
Dynom commented 3 years ago

possibly even easier would be to:

for _, te := range .. {
  te := te
}

This is a common solution and not a problem with Goblin. @viharm91 if it answers your question, can you close the issue?

viharm91 commented 3 years ago

possibly even easier would be to:

for _, te := range .. {
  te := te
}

This is a common solution and not a problem with Goblin. @viharm91 if it answers your question, can you close the issue?

Thanks @Dynom. Its much simpler fix.

viharm91 commented 3 years ago

possibly even easier would be to:

for _, te := range .. {
  te := te
}

This is a common solution and not a problem with Goblin. @viharm91 if it answers your question, can you close the issue?

For whoever finds this - the "fix" is to define the variables outside of It

      for _, te := range loopableLoop {

          expected := te.expected
          actual := te.actual
          g.It(expected, func() {
              g.Assert(expected).Equal(actual)
          })
      }

Or isolate the context

      for _, te := range loopableLoop {
          func(te struct {
              expected string
              actual   string
          }) {
              g.It(te.expected, func() {
                  g.Assert(te.expected).Equal(te.actual)
              })
          }(te)
      }

Thanks @sockol.