Skip to content

Latest commit

 

History

History
92 lines (69 loc) · 2.78 KB

nesting.md

File metadata and controls

92 lines (69 loc) · 2.78 KB

testcase nesting guide

In testcase to express certain edge cases, the framework prefers the usage of nesting.

By convention every if statement should have 2 corresponding testing context to represent possible edge cases. This is required in order to keep clean track of the code complexity. If the test coverage became too big or have too many level of nesting, that is the clear sign that the implementation has too broad scope, and the required mental model for the given production code code is likely to be big.

For implementations where you need to test business logic, testcase#Spec is suggested, even if the spec has too many nested layers. That is only represent the complexity of the component.

Flattening

When the specification becomes too big, you can improve readability by flattening the specification by refactoring out specification sub-context(s) into a function.

The added benefit for this is that all the common variables present on the top level can be accessed from each of the sub context. For e.g you can create variable with a database connection, that ensure a common way to connect and afterwards cleaning up the connection.

package examples_test

import (
	"testing"

	"github.com/stretchr/testify/require"

	"github.com/adamluzsi/testcase"
	"github.com/adamluzsi/testcase/docs/examples"
)

func TestMyStruct(t *testing.T) {
	s := testcase.NewSpec(t)
	s.NoSideEffect()

	myStruct := testcase.Let(s, func(t *testcase.T) examples.MyStruct {
		return examples.MyStruct{}
	})

	// define shared variables and hooks here
	// ...

	s.Describe(`Say`, func(s *testcase.Spec) {
		SpecMyStruct_Say(s, myStruct)
	})
	s.Describe(`Foo`, func(s *testcase.Spec) {
		SpecMyStruct_Foo(s, myStruct)
	})
	// other specification sub contexts
}

func SpecMyStruct_Say(s *testcase.Spec, myStruct testcase.Var[examples.MyStruct]) {
	var subject = func(t *testcase.T) string {
		return myStruct.Get(t).Say()
	}

	s.Then(`it will say a famous quote`, func(t *testcase.T) {
		assert.Must(t).Equal( `Hello, World!`, subject(t))
	})
}

func SpecMyStruct_Foo(s *testcase.Spec, myStruct testcase.Var[examples.MyStruct]) {
	var subject = func(t *testcase.T) string {
		return myStruct.Get(t).Foo()
	}

	s.Then(`it will say a famous quote`, func(t *testcase.T) {
		assert.Must(t).Equal( `Bar`, subject(t))
	})
}