unit-testinggomockinggomock

Gomock same method twice with different input


Note: Not a duplicate of Mock interface method twice with different input and output using testify - Different library.

I am using the github.com/golang/mock/gomock library to mock an HTTP client interface in order to test the behaviour of my code. My code uses the same Post() method on the client twice, but for 2 different endpoints.

I tried:

mockUc.EXPECT().
    Post("m-elasticsearch/_sql/translate", gomock.Eq(expectedQuery), gomock.Any(), gomock.Any()).
    SetArg(2, esQuery).
    Return(http.StatusOK, nil).
    Times(1)
mockUc.EXPECT().
    Post("m-elasticsearch/app-*/_search", gomock.Eq(esQuery), gomock.Any(), gomock.Any()).
    SetArg(2, logResults).
    Return(http.StatusOK, nil).
    Times(1)

But this gave me the error, telling me that the second EXPECT() was being considered on the first call:

 expected call at [...] doesn't match the argument at index 0.
        Got: m-elasticsearch/_sql/translate (string)
        Want: is equal to m-elasticsearch/app-*/_search (string)

I then tried using gomock.InOrder() like this:

first := mockUc.EXPECT().
    Post("m-elasticsearch/_sql/translate", gomock.Eq(expectedQuery), gomock.Any(), gomock.Any()).
    SetArg(2, esQuery).
    Return(http.StatusOK, nil).
    Times(1)
second := mockUc.EXPECT().
    Post("m-elasticsearch/app-*/_search", gomock.Eq(esQuery), gomock.Any(), gomock.Any()).
    SetArg(2, logResults).
    Return(http.StatusOK, nil).
    Times(1)

gomock.InOrder(first, second)

But this didn't help either.

Is what I'm trying to do possible here?


Solution

  • Instead of writing two EXPECTs, you can use DoAndReturn method and return the value as you want in one EXPECT. I could not write types because I do not know method signature.

        mockUc.
            EXPECT().
            Post(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
            DoAndReturn(func(url, query string, ...) (int, error) {
                if url == "m-elasticsearch/_sql/translate" {
                    return http.StatusOK, nil
                } else {
                    return http.StatusOK, nil
                }
            })