Two Go Routines Operating on a single shared mock repository - Test Fails

I am writing unit tests for my service using testify. There I am mocking my repository and calling the functions of it using the service I am trying to test.

My mock

 import (
	....
	....
	"github.com/stretchr/testify/mock"
)

type MyRepository struct {
	mock.Mock
}

func (m *MyRepository) FindAll(c cri.Criteria) ([]models.Cinema, error) {
	args := m.Called()
	if args.Error(1) != nil {
		return nil, args.Error(1)
	}
	return args.Get(0).([]models.Cinema), nil
}

The service I am trying to test

func (s *MyService) GetAll(context context.Context) (*dto.DtoList, error) {
	models, err := s.repository.FindAll(cri.NilCriteria())
	if err != nil {
		return nil, err
	}

	return dto.GetDtoList(models), nil
}

My Test file

import (
	....
	.....
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/suite"
)

type MyServiceTestSuite struct {
	suite.Suite
	myRepo    *mockRepository.MyRepository
	myService *CinemaService
}

func (suite *MyServiceTestSuite) SetupSuite() {

	suite.T().Log("Setting up test suite")

	suite.myRepo = &mockRepository.MyRepository{}

	...
	...

	suite.myService = NewMyService(suite.myRepo, suite.config)

}

func (suite *MyServiceTestSuite) TestMyService_GetAll() {

	suite.Run("Return All when no error", func() {

		suite.myRepo.On("FindAll").Return([]models.Cinema{cinemaModel1, cinemaModel2}, nil)
		allCinema2, err2 := suite.myService.GetAll(context.Background())
		suite.myRepo.AssertExpectations(suite.T())

		assert.ElementsMatch(suite.T(), expectedList.Cinemas, allCinema2.Cinemas)
		assert.Equal(suite.T(), expectedList.Cinemas[0].Id, allCinema2.Cinemas[0].Id)
		assert.Nil(suite.T(), err2)

	})

	suite.Run("Return Error when repo returns error", func() {

		noDataErr := errors.New("No Data")
		suite.myRepo.On("FindAll").Return(nil, noDataErr)
		allCinema1, err1 := suite.myService.GetAll(context.Background())
		suite.myRepo.AssertExpectations(suite.T())

		assert.Nil(suite.T(), allCinema1)
		assert.Equal(suite.T(), noDataErr, err1)

	})

}

Now my problem is, when I execute the test, it fails. The issue is in the second sub test with name “Return Error when repo returns error”. Even though I expect nil and error, it returns a cinema list and a nil as error. Basically, that is the output of the sub test with name “Return All when no error”.

I don’t understand this behaviour. But I sense that the shared myRepo has something to do with it. But why this happens? Is it because the two subtests run in parallel ? And is there any way that I can get this working without using separate instances of myRepo per each subtest?

Please if possible, explain me the reason and a way of solving this. I think I am missing some basic conceptual thing with regard to goroutines.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.