GoravelGoravel
Home
Video
  • English
  • 简体中文
GitHub
Home
Video
  • English
  • 简体中文
GitHub
  • Prologue

    • Upgrade Guide

      • Upgrading To v1.15 From v1.14
      • Upgrading To v1.14 From v1.13
      • History Upgrade
    • Contribution Guide
    • Excellent Extend Packages
  • Getting Started

    • Installation
    • Configuration
    • Directory Structure
    • Compile
  • Architecture Concepts

    • Request Lifecycle
    • Service Container
    • Service Providers
    • Facades
  • The Basics

    • Routing
    • HTTP Middleware
    • Controllers
    • Requests
    • Responses
    • Views
    • Grpc
    • Session
    • Validation
    • Logging
  • Digging Deeper

    • Artisan Console
    • Cache
    • Events
    • File Storage
    • Mail
    • Queues
    • Task Scheduling
    • Localization
    • Package Development
    • Color
    • Strings
    • Helpers
  • Security

    • Authentication
    • Authorization
    • Encryption
    • Hashing
  • ORM

    • Getting Started
    • Relationships
    • Migrations
    • Seeding
    • Factories
  • Testing

    • Getting Started
    • HTTP Tests
    • Mock

HTTP Tests

  • Introduction
  • Make Requests
    • Customize Request Headers
    • Cookies
    • WithSession
    • Debugging Responses
  • Building Body
  • Testing Json APIs
    • Asserting Exact JSON Matches
    • Fluent JSON Testing
    • Asserting Attribute Presence / Absence
    • Scoping JSON Collection Assertions
  • Available Assertions
    • Response Assertions
    • AssertAccepted
    • AssertBadRequest
    • AssertConflict
    • AssertCookie
    • AssertCookieExpired
    • AssertCookieMissing
    • AssertCookieNotExpired
    • AssertCreated
    • AssertDontSee
    • AssertExactJson
    • AssertFluentJson
    • AssertForbidden
    • AssertFound
    • AssertGone
    • AssertHeader
    • AssertHeaderMissing
    • AssertInternalServerError
    • AssertJson
    • AssertJsonMissing
    • AssertMethodNotAllowed
    • AssertMovedPermanently
    • AssertNoContent
    • AssertNotAcceptable
    • AssertNotFound
    • AssertNotModified
    • AssertOk
    • AssertPartialContent
    • AssertPaymentRequired
    • AssertRequestTimeout
    • AssertSee
    • AssertSeeInOrder
    • AssertServerError
    • AssertServiceUnavailable
    • AssertStatus
    • AssertSuccessful
    • AssertTemporaryRedirect
    • AssertTooManyRequests
    • AssertUnauthorized
    • AssertUnprocessableEntity

Introduction

When building web applications, you'll often need to test if your HTTP requests work correctly from start to finish. Goravel's testing tools make this straightforward - you can simulate requests and verify responses without setting up complex test environments.

Make Requests

Testing HTTP endpoints in Goravel uses a simple pattern. Start with the Http method from your TestCase, which needs a *testing.T parameter for assertions. This gives you a request object (framework/contracts/testing.TestRequest) that handles all common HTTP verbs like Get, Post, and Put.

Instead of making real HTTP calls, these methods simulate your application's request cycle internally. Each request returns a response object (framework/contracts/testing.TestResponse) with methods to check the results.

Here's a basic example:

func (s *ExampleTestSuite) TestIndex() {
	response, err := s.Http(s.T()).Get("/users/1")
	s.Nil(err)
	response.AssertStatus(200)
}

Customize Request Headers

You can customize request headers using either WithHeader for a single header or WithHeaders for multiple headers:

func (s *ExampleTestSuite) TestIndex() {
    // Single header
    response, err := s.Http(s.T()).WithHeader("X-Custom-Header", "Value").Get("/users/1")
    
    // Multiple headers
    response, err := s.Http(s.T()).WithHeaders(map[string]string{
        "X-Custom-Header": "Value",
        "Accept": "application/json",
    }).Get("/users/1")
}

Cookies

You may use either WithCookie or WithCookies method to set cookies value before making a request.

func (s *ExampleTestSuite) TestIndex() {
	response, err := s.Http(s.T()).WithCookie("name", "krishan").Get("/users/1")

	// or use WithHeaders for multiple Headers
	response, err := s.Http(s.T()).WithHeader(map[string]string{
        "name": "krishan",
        "lang": "en",
    }).Get("/users/1")
}

WithSession

You may set the data to the session using the WithSession method:

func (s *ExampleTestSuite) TestIndex() {
	response, err := s.Http(s.T()).WithSession(map[string]any{"role": "admin"}).Get("/users/1")
}

Debugging Responses

After making request you may use Session, Headers, Content, Cookies or Json method to check data returned from the request.

func (s *ExampleTestSuite) TestIndex() {
	response, err := s.Http(s.T()).WithSession(map[string]any{"role": "admin"}).Get("/users/1")
	
	content, err := response.Content()
	
	cookies := response.Cookies()
	
	headers := response.Headers()
	
	json, err := response.Json() // response body parsed as json(map[string]any)
	
	session, err := response.Session() // returns all values stored in the current request session
}

Building Body

For method like Post, Put, Delete etc. Goravel accepts io.Reader as second argument. To simplify building payloads, the framework provides utility methods for constructing request bodies.

import "github.com/goravel/framework/support/http"

func (s *ExampleTestSuite) TestIndex() {
    builder := http.NewBody().SetField("name", "krishan")
    
    body, err := builder.Build()

    response, err := s.Http(s.T()).WithHeader("Content-Type", body.ContentType()).Post("/users", body)
}

Testing Json APIs

Goravel provides several helpers to test JSON API responses effectively. It attempts to unmarshal the response body into a Go map[string]any. If unmarshalling fails, the associated assertions will also fail.

func (s *ExampleTestSuite) TestIndex() {
    response, err := s.Http(s.T()).WithHeader("Content-Type", body.ContentType()).Post("/users", nil)
	s.Nil(err)
	
	response.AssertStatus(201).
		AssertJson(map[string]any{
			"created": true,
        })
}

To access the unmarshalled JSON directly, use the Json method on the TestResponse. This lets you inspect individual elements of the response body.

json, err := response.Json()
s.Nil(err)
s.True(json["created"])

Tips

The AssertJson method checks whether the response contains all the specified values, even if the response includes additional fields. It doesn't require an exact match unless you use AssertExactJson.

Asserting Exact JSON Matches

If you need to verify that the response matches your expected JSON exactly (with no extra or missing fields), use the AssertExactJson method.

func (s *ExampleTestSuite) TestIndex() {
    response, err := s.Http(s.T()).WithHeader("Content-Type", body.ContentType()).Post("/users", nil)
	s.Nil(err)
	
	response.AssertStatus(201).
		AssertExactJson(map[string]any{
			"created": true,
        })
}

Fluent JSON Testing

Goravel makes it easy to perform fluent assertions on JSON responses. Using the AssertFluentJson method, you can pass a closure that provides an instance of framework/contracts/testing.AssertableJSON. This instance allows you to check specific values or conditions in the JSON response returned by your request.

For example, you can use the Where method to assert that a particular value exists in the JSON response, and the Missing method to ensure that an attribute is not present.

import contractstesting "github.com/goravel/framework/contracts/testing"

func (s *ExampleTestSuite) TestIndex() {
    response, err := s.Http(s.T()).Get("/users/1")
	s.Nil(err)
	
	response.AssertStatus(201).
		AssertFluentJson(func (json contractstesting.AssertableJSON) {
			json.Where("id", float64(1)).
				Where("name", "bowen").
				WhereNot("lang", "en").
				Missing("password")
        })
}

Asserting Attribute Presence / Absence

If you want to check whether an attribute is present or missing, Goravel makes it simple with the Has and Missing methods.

response.AssertStatus(201).
    AssertFluentJson(func (json contractstesting.AssertableJSON) {
        json.Has("username").
            Missing("password")
    })

You can also assert the presence or absence of multiple attributes at once using HasAll and MissingAll.

response.AssertStatus(201).
    AssertFluentJson(func (json contractstesting.AssertableJSON) {
        json.Has([]string{"username", "email"}).
            MissingAll([]string{"verified", "password"})
    })

If you only need to check for the presence of at least one attribute from a list, use the HasAny method.

response.AssertStatus(201).
    AssertFluentJson(func (json contractstesting.AssertableJSON) {
		json.HasAny([]string{"username", "email"})
    })

Scoping JSON Collection Assertions

When a response contains a collection of objects under a named key, you can use various methods to assert its structure and content.

type Item struct {
    ID int `json:"id"`
}

facades.Route().Get("/", func(ctx http.Context) http.Response {
    items := []Item{
        {ID: 1},
        {ID: 2},
    }
    return ctx.Response().Json(200, map[string]{
		"items": items,
    })
}

You can use the Count method to verify the number of elements in the collection. To assert properties of the first element, use the First method, which provides an instance of AssertableJson. Similarly, the Each method allows you to iterate over all elements and assert their properties individually. Alternatively, the HasWithScope method combines the functionality of First and Count, allowing you to assert both the first element and its contents while providing an AssertableJson instance for scoped assertions.

// Count and First
response.AssertStatus(200).
    AssertFluentJson(func(json contractstesting.AssertableJSON) {
        json.Count("items", 2).
            First("items", func(json contractstesting.AssertableJSON) {
                json.Where("id", 1)
            })
    })

// Each
response.AssertStatus(200).
    AssertFluentJson(func(json contractstesting.AssertableJSON) {
        json.Count("items", 2).
            Each("items", func(json contractstesting.AssertableJSON) {
                json.Has("id")
            })
    })

// HasWithScope
response.AssertStatus(200).
    AssertFluentJson(func(json contractstesting.AssertableJSON) {
        json.HasWithScope("items", 2, func(json contractstesting.AssertableJSON) {
            json.Where("id", 1)
        })
    })

Available Assertions

Response Assertions

AssertAcceptedAssertBadRequestAssertConflict
AssertCookieAssertCookieExpiredAssertCookieMissing
AssertCookieNotExpiredAssertCreatedAssertDontSee
AssertExactJsonAssertFluentJsonAssertForbidden
AssertFoundAssertGoneAssertHeader
AssertHeaderMissingAssertInternalServerErrorAssertJson
AssertJsonMissingAssertMethodNotAllowedAssertMovedPermanently
AssertNoContentAssertNotAcceptableAssertNotFound
AssertNotModifiedAssertOkAssertPartialContent
AssertPaymentRequiredAssertRequestTimeoutAssertSee
AssertSeeInOrderAssertServerErrorAssertServiceUnavailable
AssertStatusAssertSuccessfulAssertTemporaryRedirect
AssertTooManyRequestsAssertUnauthorizedAssertUnprocessableEntity

AssertAccepted

Asserts that the response has an 202 Accepted HTTP status code:

response.AssertAccepted()

AssertBadRequest

Asserts that the response has a 400 Bad Request HTTP status code:

response.AssertBadRequest()

AssertConflict

Asserts that the response has a 409 Conflict HTTP status code:

response.AssertConflict()

AssertCookie

Asserts that the response contains a cookie with the specified name and value:

response.AssertCookie("name", "value")

AssertCookieExpired

Asserts that the specified cookie has expired:

response.AssertCookieExpired("name")

AssertCookieMissing

Asserts that the response does not contain a cookie with the specified name:

response.AssertCookieMissing("name")

AssertCookieNotExpired

Asserts that the specified cookie has not expired:

response.AssertCookieNotExpired("name")

AssertCreated

Asserts that the response has a 201 Created HTTP status code:

response.AssertCreated()

AssertDontSee

Asserts that the response does not contain the specified values. The second parameter (optional) determines whether to escape special characters in the values before checking. If not provided, it defaults to true.

response.AssertDontSee([]string{"<div>"}, false)  // Do not escape special characters

AssertExactJson

Asserts that the response JSON matches exactly the provided map[string]any:

response.AssertExactJson(map[string]any{"created": true})

AssertFluentJson

Asserts the response JSON using a fluent interface:

import contractstesting "github.com/goravel/framework/contracts/testing"

response.AssertFluentJson(func(json contractstesting.AssertableJSON) {
     json.Where("created", true)
})

AssertForbidden

Asserts that the response has a 403 Forbidden HTTP status code:

response.AssertForbidden()

AssertFound

Asserts that the response has a 302 Found HTTP status code:

response.AssertFound()

AssertGone

Asserts that the response has a 410 Gone HTTP status code:

response.AssertGone()

AssertHeader

Asserts that the response contains the specified header with the given value:

response.AssertHeader("Content-Type", "application/json")

AssertHeaderMissing

Asserts that the response does not contain the specified header:

response.AssertHeaderMissing("X-Custom-Header")

AssertInternalServerError

Asserts that the response has a 500 Internal Server Error HTTP status code:

response.AssertInternalServerError()

AssertJson

Asserts that the response JSON contains the provided fragment:

response.AssertJson(map[string]any{"created": true})

AssertJsonMissing

Asserts that the specified keys or values are missing in the response JSON:

response.AssertJsonMissing(map[string]any{"created": false})

AssertMethodNotAllowed

Asserts that the response has a 405 Method Not Allowed HTTP status code:

response.AssertMethodNotAllowed()

AssertMovedPermanently

Asserts that the response has a 301 Moved Permanently HTTP status code:

response.AssertMovedPermanently()

AssertNoContent

Asserts that the response has a 204 No Content HTTP status code:

response.AssertNoContent()

AssertNotAcceptable

Asserts that the response has a 406 Not Acceptable HTTP status code:

response.AssertNotAcceptable()

AssertNotFound

Asserts that the response has a 404 Not Found HTTP status code:

response.AssertNotFound()

AssertNotModified

Asserts that the response has a 304 Not Modified HTTP status code:

response.AssertNotModified()

AssertOk

Asserts that the response has a 200 OK HTTP status code:

response.AssertOk()

AssertPartialContent

Asserts that the response has a 206 Partial Content HTTP status code:

response.AssertPartialContent()

AssertPaymentRequired

Asserts that the response has a 402 Payment Required HTTP status code:

response.AssertPaymentRequired()

AssertRequestTimeout

Asserts that the response has a 408 Request Timeout HTTP status code:

response.AssertRequestTimeout()

AssertSee

Asserts that the response contains the specified values. The second parameter (optional) determines whether to escape special characters in the values before checking. If not provided, it defaults to true.

response.AssertSee([]string{"<div>"}, false)  // Do not escape special characters

AssertSeeInOrder

Asserts that the response contains the specified values in the given order. The second parameter (optional) determines whether to escape special characters in the values before checking. If not provided, it defaults to true.

response.AssertSeeInOrder([]string{"First", "Second"}, false)  // Do not escape special characters

AssertServerError

Asserts that the response has a server error (>= 500 , < 600) HTTP status code:

response.AssertServerError()

AssertServiceUnavailable

Asserts that the response has a 503 Service Unavailable HTTP status code:

response.AssertServiceUnavailable()

AssertStatus

Asserts that the response has the specified HTTP status code:

response.AssertStatus(200)

AssertSuccessful

Asserts that the response has a successful HTTP status code (2xx):

response.AssertSuccessful()

AssertTemporaryRedirect

Asserts that the response has a 307 Temporary Redirect HTTP status code:

response.AssertTemporaryRedirect()

AssertTooManyRequests

Asserts that the response has a 429 Too Many Requests HTTP status code:

response.AssertTooManyRequests()

AssertUnauthorized

Asserts that the response has a 401 Unauthorized HTTP status code:

response.AssertUnauthorized()

AssertUnprocessableEntity

Asserts that the response has a 422 Unprocessable Entity HTTP status code:

response.AssertUnprocessableEntity()
Edit this page
Prev
Getting Started
Next
Mock