franela/goblin

Table driven tests will test only last item

viharm91 opened this issue ยท 4 comments

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)
			})
		}
	})
}

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

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?

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.

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.