title: How to properly mock a struct with member functions in Golang?
body: <p>I have two structs: <code>FunctionalityClient</code> and <code>TestClient</code>, both implementing  <code>Interface</code>. I have a global variable <code>Client</code> of type <code>Interface</code>. I assign to <code>Client</code> either the actual client, or the mock client, depending on whether it's a test or a normal run.</p>
  
  <p><code>Interface</code> has a method <code>Request</code> that I want to mock in tests. That is, I want to:</p>
  
  <ul>
  <li>record what were the argument passed to the function</li>
  <li>return some arbitrarily defined return value from the function</li>
  </ul>
  
  <p>So the struct looks like this:</p>
  
  <pre><code>type TestClient struct {
       recordedArgs []interface{}
       returnValues []interface{}
  }
  func (c *TestClient) Request(body io.Reader, method string, endpoint string, headers []Header) ([]byte, error) {
      c.recordedArgs = append(c.recordedArgs, []interface{}{body, method, endpoint, headers})  // this can't be typed if I want the code to be reusable
          if len(c.returnValues) != 0 {
          last := c.returnValues[0]
          c.returnValues = c.returnValues[1:]
          return last.([]byte), nil
      }
      return nil, nil
  }
  </code></pre>
  
  <p>And I use it like so:</p>
  
  <pre><code>testClient := TestClient{
      returnValues: []interface{}{
          []byte("arbitrarily defined return value"),
          []byte("this will be returned after calling Request a second time"),
      }
  }
  Client = &amp;testClient
  // run the test
  // now let's check the results
  r1 := testClient.recordedArgs[1].([]interface{})  // because I append untyped lists to recordedArgs
  assert.Equal(t, "POST", r1[1].(string))
  assert.Equal(t, "/file", r1[2].(string))
  // and so on
  </code></pre>
  
  <p><strong>Now the question.</strong></p>
  
  <p>I have a few structs that I want to mock like this. Currently I just copy and paste the code above for each struct. But that really sucks, I would like the mock logic to be abstracted away somehow. I would also accept something like Mockito's <code>when</code>: when the mocked function is called with specific arguments, return a specific value and record the call.</p>
  
  <p>How can I properly mock a struct with member functions in Golang?</p>