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.