testify: assert dont fail when nil is expected

Hey there,

I’ve a strange behavior, I might miss something or do something wrong.

I am currently using testify/assert and testify/suite

with :

type MyTestSuite struct {
	suite.Suite
    // some custom field
    db
}

func TestMyTestSuite(t *testing.T) {
     // init db
     // blabla

    suite.Run(t, &MyTestSuite{
        db
    })
}

func (s *MyTestSuite) TearDownTest() {
	s.db.Query(nil, "DELETE FROM table;")
}

func (s *MyTestSuite) TestMyFunc() {

    foo, err := MyFunc(bar)

    assert.NotNil(s.T(), err) // err is nil here but dont fail
    assert.Nil(s.T(), foo)
    assert.Equal(s.T(), err.Error(), "failed")  // thus SIGSEGV happend here

   // followed by a lot of test after and more assert
}

The problem is that I have a SIGSEGV on assert.Equal(s.T(), err.Error(), "failed")

because err is nil but it should not happen since I check assert.NotNil(s.T(), err) right before.

I dont know why it pass, did I miss something somewhere ?

Thanks for your time, Tommy

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 7
  • Comments: 24 (4 by maintainers)

Most upvoted comments

The test isn’t suppose to stop after an assert fails. The readme specifies that you need to do this:

  // assert for not nil (good when you expect something)
  if assert.NotNil(t, object) {

    // now we know that object isn't nil, we are safe to make
    // further assertions without causing any errors
    assert.Equal(t, "Something", object.Value)

  }

You can access require.Assertions via suite.Suite{}.Require().

For anyone who is interested (@Tommy-42 ), you can make your own custom suite.Suite struct, which will default to using require.Assertions, instead of the assert.Assertions by doing the following.

// Suite is copied directly from testify/suite, the only difference being
// that it nests require.Assertions, instead of the assert.Assertions.
// This changes the default behavior of suite.Equal() et al. to fail on
// the first test that fails.
//
// Regular assertions can be accessed via suite.Assert().
//
// All other behavior of the suite should be exactly the same as the
// testify suite.
type Suite struct {
	*require.Assertions
	assert *assert.Assertions
	t      *testing.T
}

func (s *Suite) T() *testing.T {
	return s.t
}

// SetT sets the current *testing.T context.
func (s *Suite) SetT(t *testing.T) {
	s.t = t
	s.assert = assert.New(t)
	s.Assertions = require.New(t)
}

func (s *Suite) Assert() *assert.Assertions {
	if s.assert == nil {
		s.assert = assert.New(s.T())
	}
	return s.assert
}

func (s *Suite) Require() *require.Assertions {
	if s.Assertions == nil {
		s.Assertions = require.New(s.T())
	}
	return s.Assertions
}

Use this as you would the normal suite.Suite.

@devdinu Pretty sure this ticket can be closed based on @serbrech 's comment.

@ghostsquad That’s what the require package is for.

@devdinu It was a misunderstanding on my part. I was expecting the fatal error like in the require package.

+1 on this issue. Also have cases where assert.Equal doesn’t fail when two integers are not equal.

@devdinu thanks for your comment; I changed the code and it works. Do you have an explanation for this issue?

fmt.Println(err == nil) // this prints true 

I’ve tested with assert.Error() / assert.NoError() since it looks like more appropriate for asserting error , but I got the same behavior.

@ghostsquad That’s what this thread is about, people who got confused that their tests did not fail. I think that’s because in most other languages, assert libraries will fail the test right away, because you don’t write tests with loops.