2017-01-30 2 views
0

ich ein REST-API in Go implementiert habe Go-Gin mit und ich versuche, eine Handler-Funktion zu testen, die wie die folgendenWie lustig zu machen, während HTTP-Anfrage an API Senden

func editNameHandler(c *gin.Context) { 
     // make a ReST call to another server 
     callToAnotherServer() 
     c.Status(200) 
} 

ich verspotten sehen wollen zu callToAnotherServer Methode, so dass mein Testfall den Drittanbieterserver überhaupt nicht aufruft.

Mein Testfall sieht aus wie

func TestSeriveIdStatusRestorePatch(t *testing.T) { 

    // Request body 
    send := strings.NewReader(`{"name":"Robert"}` 

    // this function sends an HTTP request to the API which ultimately calls editNameHandler 
    // Ignore the variables.The variables are retrieved in code this is to simplify question 
    ValidTokenTestPatch(API_VERSION+"/accounts/"+TestAccountUUID+"/students/"+TestStudentId, t, send, http.StatusOK)   
} 

ich durch Mock functions in Go ging die erwähnt, wie wir eine Funktion zu verspotten passieren kann. Ich frage mich, wie wir eine Funktion übergeben können, während http-Anfrage senden? Wie kann ich in diesem Fall die Funktion nachahmen? Was ist die beste Praxis?

+1

Siehe https://godoc.org/net/http/httptest#Server –

Antwort

0

Ich glaube nicht, dass es eine einzige Antwort für diese Frage gibt, aber ich werde meinen Ansatz teilen, wie ich derzeit Dependency Injection on Go mit Go-Gin mache (sollte aber fast das gleiche mit allen anderen sein Router).

Aus geschäftlicher Sicht habe ich eine Struktur, die alle Zugriff auf meine Dienste, die für Geschäftsregeln/Verarbeitung verantwortlich sind, umschließt.

// WchyContext is an application-wide context 
type WchyContext struct { 
    Health services.HealthCheckService 
    Tenant services.TenantService 
    ... whatever 
} 

Meine Dienste sind dann nur Schnittstellen.

// HealthCheckService is a simple general purpose health check service 
type HealthCheckService interface { 
    IsDatabaseOnline() bool 
} 

Welche mulitple Implementierungen haben, wie MockedHealthCheck, PostgresHealthCheck, PostgresTenantService und so weiter.

als Mein Router auf einem WchyContext abhängt, das der Code wie folgt aussieht:

func GetMainEngine(ctx context.WchyContext) *gin.Engine { 
    router := gin.New() 
    router.Use(gin.Logger()) 
    router.GET("/status", Status(ctx)) 
    router.GET("/tenants/:domain", TenantByDomain(ctx)) 
    return router 
}` 

Status und TenantByDomain wirkt wie eine Handler-Fabrik, die alle es tut, sind einen neuen Handler auf gegebenen Kontext schaffen basierten, wie dies:

type statusHandler struct { 
    ctx context.WchyContext 
} 

// Status creates a new Status HTTP handler 
func Status(ctx context.WchyContext) gin.HandlerFunc { 
    return statusHandler{ctx: ctx}.get() 
} 

func (h statusHandler) get() gin.HandlerFunc { 
    return func(c *gin.Context) { 
     c.JSON(200, gin.H{ 
      "healthy": gin.H{ 
       "database": h.ctx.Health.IsDatabaseOnline(), 
      }, 
      "now":  time.Now().Format("2006.01.02.150405"), 
     }) 
    } 
} 

Wie Sie sehen können, meine Gesundheits-Check-Handler kümmert sich nicht um die konkrete Umsetzung meiner Leistungen, ich kann es nur verwenden, was in der ctx.

ist 210

Der letzte Teil hängt von der aktuellen Ausführungsumgebung ab. Während automatisierten Tests erstelle ich eine neue WchyContext mit verspottet/stubbed Dienste und es GetMainEngine senden, wie folgt aus:

ctx := context.WchyContext{ 
    Health: &services.InMemoryHealthCheckService{Status: false}, 
    Tenant: &services.InMemoryTenantService{Tenants: []*models.Tenant{ 
     &models.Tenant{ID: 1, Name: "Orange Inc.", Domain: "orange"}, 
     &models.Tenant{ID: 2, Name: "The Triathlon Shop", Domain: "trishop"}, 
    }} 
} 
router := handlers.GetMainEngine(ctx) 

request, _ := http.NewRequest(method, url, nil) 
response := httptest.NewRecorder() 
router.ServeHTTP(response, request) 
... check if response matches what you expect from your handler 

Und wenn Sie Setup es wirklich hören auf einen HTTP-Port, die Verkabelung bis sieht wie folgt aus:

Es gibt ein paar Dinge, die ich nicht mag, ich werde es wahrscheinlich später verbessern/verbessern, aber es hat bisher gut funktioniert.

Wenn Sie vollständige Referenz-Code sehen wollen, arbeite ich an diesem Projekt hier https://github.com/WeCanHearYou/wchy

Hoffe, dass es Ihnen irgendwie helfen kann.

Verwandte Themen