title: Unit Testing With Gin-Gonic
body: <p>My project is split into three main components: controllers, services, and models. When a route is queried via the URI, the controllers are called, which then call the services to interact with the models, which then interact with the database via gorm.</p>
  
  <p>I am trying to write unit tests for the controllers, but I'm having a hard time understanding how to properly mock the services layer while mocking the gin layer. I can get a mocked gin context, but I'm not able to mock the service layer within my controller method. Below is my code:</p>
  
  <p>resourceController.go</p>
  
  <pre><code>package controllers
  
  import (
      "MyApi/models"
      "MyApi/services"
      "github.com/gin-gonic/gin"
      "net/http"
  )
  
  func GetResourceById(c *gin.Context) {
      id := c.Param("id")
      resource, err := services.GetResourceById(id)
  
      if err != nil {
          c.JSON(http.StatusBadRequest, gin.H{"status": http.StatusBadRequest, "message": err})
          return
      } else if resource.ID == 0 {
          c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "Resource with id:"+id+" does not exist"})
          return
      }
  
      c.JSON(http.StatusOK, gin.H{
          "id": resource.ID,
          "data1": resource.Data1,
          "data2": resource.Data2,
      })
  }
  
  </code></pre>
  
  <p>I want to test that the c.JSON is returning with the proper <code>http</code> status and other data. I need to mock the <code>id</code> variable, <code>err</code> variable, and <code>c.JSON</code> function, but when I try to set the <code>c.JSON</code> function in the test to my new function, I get an error saying <code>Cannot assign to c.JSON</code>.
  Below is my attempt at writing a test:</p>
  
  <p>resourceController_test.go</p>
  
  <pre><code>package controllers
  
  import (
      "github.com/gin-gonic/gin"
      "github.com/stretchr/testify/assert"
      "net/http/httptest"
      "testing"
  )
  
  func TestGetResourceById(t *testing.T) {
      var status int
      var body interface{}
      c, _ := gin.CreateTestContext(httptest.NewRecorder())
      c.JSON = func(stat int, object interface{}) {
          status = stat
          body = object
      }
      GetResourceById(c)
      assert.Equal(t, 4, 4)
  }
  
  </code></pre>
  
  <p>How do I properly write a unit test to test whether the c.JSON is returning the proper values?</p>