0

I'm trying to write unit tests mocking service calls being made using GoMocks and It's been a real struggle.

One way I'm trying to simplify the code is to make a private method that gives a good response for all the mocks and then in each individual test that needs a different response of a mock call (e.g., testing a mock failure), I want to override that call with a different response.

e.g., of the setupMocks fn (scrubbed)

func setupMocks(s *SSAdapterV1Suite, userId string) {
    s.mockDBDao.EXPECT().Mark(userId, gomock.Any()).
        Return(nil)
    s.mockDBDao.EXPECT().Get(userId).
        Return(userData, nil)
    s.mockDBDao.EXPECT().Delete(gomock.Any(), gomock.Any()).
        Return(nil)
}

When I use the setupMocks fn in the "Success" scenario, it works fine.

However, if I try to use it in another unit test where I want to test how an error in the service call will get handled, gomocks will use the mockResponse setup in the setupMocks fn instead of the one which I wanted to override with.

Is there a call or something I can do in GoMocks to override a mock EXPECT() response with something else instead of appending the callstack?

ThinkBonobo
  • 15,487
  • 9
  • 65
  • 80

1 Answers1

1

I didn't really see any sort of method in the GoMocks code that offered this functionality.

One way, that I saw was that you can manipulate the callstack in the gomock controller manually to try to get what you want. This might be more complicated than it's worth though. An luckily I found a simpler workaround looking at the comments in this thread: https://github.com/golang/mock/issues/137#issuecomment-440370200

What you can do is call your override BEFORE you call setupMocks(). By doing the overrides in reverse order, you'll get the effect that you want.

e.g.,

func (s *SSAdapterV1Suite) DeleteFails_Returns500() {
    // Setup
    req := makeRequest()

    // Overrides need to go before setupMocks as a workaround for no mock override support.
    // This may change in the future (c.f., https://github.com/golang/mock/issues/137#issuecomment-440370200)
    expectedErrMsg := fmt.Errorf("Forced failure")
    s.mockDBDao.EXPECT().
        Delete(gomock.Any(), gomock.Any()).
        Return(expectedErrMsg)
    setupMocks(s, req.GetUserID())

    // Run
    resp, _ := s.server.RunTheThing(context.Background(), req)

    // Assert
    require.Equal(s.T(), int32(http.StatusInternalServerError), resp.GetStatus().GetCode())
    require.Equal(s.T(), "", resp.GetStatus().GetError())
}

Note createing the mock struct and connecting it to ctrl was done in the SetupTests() fn and connected as a variable to the SSAdapterV1Suite.

ThinkBonobo
  • 15,487
  • 9
  • 65
  • 80