0

I want to mock memcache cache data in go lang to avoid authhorization i tried with gomock but couldn't work out as i dont have any interface for it.

func getAccessTokenFromCache(accessToken string)

func TestSendData(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockObj := mock_utils.NewMockCacheInterface(mockCtrl)
mockObj.EXPECT().GetAccessToken("abcd") 
var jsonStr = []byte(`{
    "devices": [
        {"id": "avccc",

        "data":"abcd/"
        }
            ]
}`)
req, err := http.NewRequest("POST", "/send/v1/data", 
bytes.NewBuffer(jsonStr))
req.Header.Set("Content-Type", "application/json")
 req.Header.Set("Authorization", "d958372f5039e28")

rr := httptest.NewRecorder()
handler := http.HandlerFunc(SendData)
handler.ServeHTTP(rr, req)
if status := rr.Code; status != 200 {
    t.Errorf("handler returned wrong status code: got %v want %v",
        status, http.StatusOK)
}
expected := `{"error":"Invalid access token"}`
body, _ := ioutil.ReadAll(rr.Body)

if string(body) != expected {
    t.Errorf("handler returned unexpected body: got %v want %v",
        string(body), expected)
}




func SendData(w http.ResponseWriter, r *http.Request) {

accessToken := r.Header.Get(constants.AUTHORIZATION_HEADER_KEY)

t := utils.CacheType{At1: accessToken}
a := utils.CacheInterface(t)
isAccessTokenValid := utils.CacheInterface.GetAccessToken(a, accessToken)

if !isAccessTokenValid {
    RespondError(w, http.StatusUnauthorized, "Invalid access token")
    return
}
response := make(map[string]string, 1)
response["message"] = "success"
RespondJSON(w, http.StatusOK, response)

}

tried to mock using gomock

package mock_utils

gen mock for utils for get access controler (1) Define an interface that you wish to mock.

(2) Use mockgen to generate a mock from the interface. (3) Use the mock in a test:

1 Answers1

0

You need to architect your code such that every such access to a service happens via an interface implementation. In your case, you should ideally create an interface like

type CacheInterface interface {
      Set(key string, val interface{}) error
      Get(key string) (interface{},error)
}

Your MemcacheStruct should implement this interface and all your memcache related calls should happen from there. Like in your case GetAccessToken should call cacheInterface.get(key) wherein your cacheInterface should refer to memcache implementation of this interface. This is a way better way to design your go programs and this would not only help you in writing tests but would also help in case let's say you want to use a different in memory database to help with caching. Like for ex., let's say in future if you want to use redis as your cache storage, then all you need to change is create a new implementation of this interface.

Kevin Sandow
  • 4,003
  • 1
  • 20
  • 33
Abhishek Sinha
  • 435
  • 4
  • 12
  • thanks for your reply i m done with make it as interface but unable to mock i m using gmock.....mockObj.EXPECT().GetAccessToken("abcd") but its throwing error like controller.go:200: missing call(s) to *mock_utils.MockCacheInterface.GetToken(is equal to abcd) – Swagata Mondal Apr 08 '18 at 11:03
  • Some things from you code is not clear. How is your utils package implementing the CacheInterface. Seems like you code is using `utis.CacheInterface.GetAccessToken()` call but I am not sure how `utils.CacheInterface` is resolving it to implementation. My guess is probably you will need to set `utils.CacheInterface` to the mocked implementation of `CacheInterface` before calling the http handler. Probably `utils.CacheInterface=mockObj` – Abhishek Sinha Apr 09 '18 at 10:00
  • What is this design pattern called? facade? – Nilesh Dec 10 '19 at 12:00