-2

I am learning to do unit testing using mocks in Go for the first time, using gomock's mockgen utility. My unit tests work fine except for one of them. The method-under-test has two dependencies: one on a database, and the other on an external service it makes rest api calls to. The mock for the database (mockRepo) works fine in that the method-under-test properly invokes the mock instead of the actual repo code. The mock for the rest client, however, continues to invoke the actual rest client and not the mock code. I can't figure out why. Can someone explain why and help fix?

Here is my unit test:

func TestService_CreateWorkspace(t *testing.T) {
    ts := NewTestService(t)
    defer ts.mockCtrl.Finish()

    ts.mockClient.EXPECT().POST(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).Return(&http.Response{StatusCode: 200}, nil)

    testWs := TestWorkspaces()["max-ws"]
    ts.mockRepo.EXPECT().Create(testWs).Times(1).Return(&testWs, nil)

    ws, err := ts.service.CreateWorkspace(&testWs)

    assert.Equal(t, testWs, ws)
    assert.NoError(t, err)
}

Here is the code for NewTestService:

type TestService struct {
    mockCtrl   *gomock.Controller
    mockClient *MockRestClient
    mockRepo   *MockRepository
    service    Service
}

func NewTestService(t *testing.T) *TestService {
    mockCtrl := gomock.NewController(t)
    mockRepo := NewMockRepository(mockCtrl)
    mockClient := NewMockRestClient(mockCtrl)
    return &TestService{
        mockCtrl:   mockCtrl,
        mockClient: mockClient,
        mockRepo:   mockRepo,
        service:    NewService(mockRepo),
    }
}

Is there an issue with assigning the same mock controller to two different mock objects? Not really sure what's going on here. Any help appreciated.

A.A.
  • 402
  • 1
  • 4
  • 19
  • 1
    Looks like `TestService` doesn't do much of anything, its `service` field is what's actually being tested. But the `NewService` call takes only the mock repo, not the mock client. You'll need some way to inject the mock client into the actual `Service` for it to use it for anything. – Adrian Apr 23 '19 at 18:55
  • Correct, TestService was just struct to bundle everything together. Yes, I see what you are saying, need to inject mockClient somehow. – A.A. Apr 23 '19 at 18:59

1 Answers1

0

I resolved this as Adrian in the comments above suggested. I was missing a way to pass the mock client into the NewService and ended up adding a client parameter to NewService.

A.A.
  • 402
  • 1
  • 4
  • 19