github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/docs/assets/js/15.36df2a66.js (about)

     1  (window.webpackJsonp=window.webpackJsonp||[]).push([[15],{387:function(t,s,e){"use strict";e.r(s);var a=e(25),n=Object(a.a)({},(function(){var t=this,s=t.$createElement,e=t._self._c||s;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"testing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testing"}},[t._v("#")]),t._v(" Testing "),e("Badge",{attrs:{text:"Since v2.2.0"}})],1),t._v(" "),e("p"),e("div",{staticClass:"table-of-contents"},[e("ul",[e("li",[e("a",{attrs:{href:"#introduction"}},[t._v("Introduction")])]),e("li",[e("a",{attrs:{href:"#http-tests"}},[t._v("HTTP Tests")]),e("ul",[e("li",[e("a",{attrs:{href:"#request-and-response"}},[t._v("Request and response")])]),e("li",[e("a",{attrs:{href:"#timeout"}},[t._v("Timeout")])]),e("li",[e("a",{attrs:{href:"#testing-json-reponses"}},[t._v("Testing JSON reponses")])]),e("li",[e("a",{attrs:{href:"#multipart-and-file-upload"}},[t._v("Multipart and file upload")])])])]),e("li",[e("a",{attrs:{href:"#testing-middleware"}},[t._v("Testing middleware")])]),e("li",[e("a",{attrs:{href:"#testsuite-reference"}},[t._v("TestSuite reference")])]),e("li",[e("a",{attrs:{href:"#database-testing"}},[t._v("Database testing")]),e("ul",[e("li",[e("a",{attrs:{href:"#generators"}},[t._v("Generators")])]),e("li",[e("a",{attrs:{href:"#using-factories"}},[t._v("Using factories")])]),e("li",[e("a",{attrs:{href:"#seeders"}},[t._v("Seeders")])])])])])]),e("p"),t._v(" "),e("h2",{attrs:{id:"introduction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),e("p",[t._v("Goyave provides an API to ease the unit and functional testing of your application. This API is an extension of "),e("a",{attrs:{href:"https://github.com/stretchr/testify",target:"_blank",rel:"noopener noreferrer"}},[t._v("testify"),e("OutboundLink")],1),t._v(". "),e("code",[t._v("goyave.TestSuite")]),t._v(" inherits from testify's "),e("code",[t._v("suite.Suite")]),t._v(", and sets up the environment for you. That means:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("GOYAVE_ENV")]),t._v(" environment variable is set to "),e("code",[t._v("test")]),t._v(" and restored to its original value when the suite is done.")]),t._v(" "),e("li",[t._v("All tests are run using your project's root as working directory. This directory is determined by the presence of a "),e("code",[t._v("go.mod")]),t._v(" file.")]),t._v(" "),e("li",[t._v("Config and language files are loaded before the tests start. As the environment is set to "),e("code",[t._v("test")]),t._v(", you "),e("strong",[t._v("need")]),t._v(" a "),e("code",[t._v("config.test.json")]),t._v(" in the root directory of your project.")])]),t._v(" "),e("p",[t._v("This setup is done by the function "),e("code",[t._v("goyave.RunTest")]),t._v(", so you shouldn't run your test suites using testify's "),e("code",[t._v("suite.Run()")]),t._v(" function.")]),t._v(" "),e("p",[t._v("The following example is a "),e("strong",[t._v("functional")]),t._v(" test and would be located in the "),e("code",[t._v("test")]),t._v(" package.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"my-project/http/route"')]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"github.com/System-Glitch/goyave/v2"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("type")]),t._v(" CustomTestSuite "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("struct")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    goyave"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("TestSuite\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("CustomTestSuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("TestHello")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("RunServer")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("route"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Register"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n        resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Get")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/hello"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NotNil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" resp "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n            "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n            suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusCode"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n            suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Hi!"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("TestCustomSuite")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("t "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("testing"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("T"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    goyave"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("RunTest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("t"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("new")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("CustomTestSuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("We will explain in more details what this test does in the following sections, but in short, this test runs the server, registers all your application routes and executes the second parameter as a server startup hook. The test requests the "),e("code",[t._v("/hello")]),t._v(" route with the method "),e("code",[t._v("GET")]),t._v(" and checks the content of the response. The server automatically shuts down after the hook is executed and before "),e("code",[t._v("RunServer")]),t._v(" returns. See the available assertions in the "),e("a",{attrs:{href:"https://pkg.go.dev/github.com/stretchr/testify",target:"_blank",rel:"noopener noreferrer"}},[t._v("testify's documentation"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("This test is a "),e("strong",[t._v("functional")]),t._v(" test. Therefore, it requires route registration and should be located in the "),e("code",[t._v("test")]),t._v(" package.")]),t._v(" "),e("div",{staticClass:"custom-block warning"},[e("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),e("p",[t._v("Because tests using "),e("code",[t._v("goyave.TestSuite")]),t._v(" are using the global config, are changing environment variables and working directory and often bind a port, they are "),e("strong",[t._v("not run in parallel")]),t._v(" to avoid conflicts. You don't have to use "),e("code",[t._v("-p 1")]),t._v(" in your test command, test suites execution is locked by a mutex.")])]),t._v(" "),e("h2",{attrs:{id:"http-tests"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#http-tests"}},[t._v("#")]),t._v(" HTTP Tests")]),t._v(" "),e("p",[t._v("As shown in the example in the introduction, you can easily run a test server and send requests to it using the "),e("code",[t._v("suite.RunServer()")]),t._v(" function.")]),t._v(" "),e("p",[t._v("This function takes two parameters.")]),t._v(" "),e("ul",[e("li",[t._v("The first is a route registrer function. You should always use your main route registrer to avoid unexpected problems with inherited middleware and route groups.")]),t._v(" "),e("li",[t._v("The second parameter is a startup hook for the server, in which you will be running your test procedure.")])]),t._v(" "),e("p",[t._v("This function is the equivalent of "),e("code",[t._v("goyave.Start")]),t._v(", but doesn't require a "),e("code",[t._v("goyave.Stop()")]),t._v(" call: the server stops automatically when the startup hook is finished. All startup hooks are then cleared. The function returns when the server is properly shut down.")]),t._v(" "),e("p",[t._v("If you registered startup hooks in your main function, these won't be executed. If you need them for your tests, you need to register them before calling "),e("code",[t._v("suite.RunServer()")]),t._v(".")]),t._v(" "),e("h3",{attrs:{id:"request-and-response"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#request-and-response"}},[t._v("#")]),t._v(" Request and response")]),t._v(" "),e("p",[t._v("There are helper functions for the following HTTP methods:")]),t._v(" "),e("ul",[e("li",[t._v("GET")]),t._v(" "),e("li",[t._v("POST")]),t._v(" "),e("li",[t._v("PUT")]),t._v(" "),e("li",[t._v("PATCH")]),t._v(" "),e("li",[t._v("DELETE")])]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("p",[e("em",[t._v("Note")]),t._v(": The "),e("code",[t._v("Get")]),t._v(" function doesn't have a third parameter as GET requests shouldn't have a body. The headers and body are optional, and can be "),e("code",[t._v("nil")]),t._v(".")]),t._v(" "),e("p",[t._v("The response body can be retrieved easily using "),e("a",{attrs:{href:"#suite-getbody"}},[e("code",[t._v("suite.GetBody(response)")])]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Get")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/get"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"response content"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h4",{attrs:{id:"url-encoded-requests"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#url-encoded-requests"}},[t._v("#")]),t._v(" URL-encoded requests")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("headers "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"application/x-www-form-urlencoded; param=value"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nresp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Post")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/product"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" headers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" strings"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewReader")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"field=value"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"response content"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h4",{attrs:{id:"json-requests"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#json-requests"}},[t._v("#")]),t._v(" JSON requests")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("headers "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"application/json"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nbody"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("_")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Marshal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"name"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Pizza"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"price"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Post")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/product"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" headers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" bytes"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewReader")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"response content"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("If you need to test another method, you can use the "),e("a",{attrs:{href:"#testsuite-request"}},[e("code",[t._v("suite.Request()")])]),t._v(" function.")])]),t._v(" "),e("h3",{attrs:{id:"timeout"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#timeout"}},[t._v("#")]),t._v(" Timeout")]),t._v(" "),e("p",[e("code",[t._v("goyave.TestSuite")]),t._v(" has a default timeout value of "),e("strong",[t._v("5 seconds")]),t._v(". This timeout is used for the "),e("code",[t._v("RunServer")]),t._v(" function as well as for the request functions("),e("code",[t._v("Get")]),t._v(", "),e("code",[t._v("Post")]),t._v(", etc.). If the timeout expires, the test fails. This prevents your test from freezing if something goes wrong.")]),t._v(" "),e("p",[t._v("The timeout can be modified as needed using "),e("code",[t._v("suite.SetTimeout()")]),t._v(":")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetTimeout")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v(" time"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Second"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h3",{attrs:{id:"testing-json-reponses"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testing-json-reponses"}},[t._v("#")]),t._v(" Testing JSON reponses")]),t._v(" "),e("p",[t._v("It is very likely that you will need to check the content of a JSON response when testing your application. Instead of unmarshaling the JSON yourself, Goyave provides the "),e("a",{attrs:{href:"#suite-getjsonbody"}},[e("code",[t._v("suite.GetJSONBody")])]),t._v(" function. This function decodes the raw body of the request. If the data cannot be decoded, or is invalid JSON, the test fails and the function returns "),e("code",[t._v("nil")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("RunServer")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("route"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Register"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Get")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/product"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        json "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n        err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetJSONBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You should always check parsing error before continuing.")]),t._v("\n            suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"field"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n            suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("float64")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("42")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" json"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"number"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h3",{attrs:{id:"multipart-and-file-upload"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multipart-and-file-upload"}},[t._v("#")]),t._v(" Multipart and file upload")]),t._v(" "),e("p",[t._v("You may need to test requests requiring file uploads. The best way to do this is using Go's "),e("code",[t._v("multipart.Writer")]),t._v(". Goyave provides functions to help you create a Multipart form.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("RunServer")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("route"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Register"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" path "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"profile.png"')]),t._v("\n    body "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("bytes"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Buffer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n    writer "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" multipart"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewWriter")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("WriteField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"email"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"johndoe@example.org"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("WriteFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" path"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"profile_picture"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" filepath"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Base")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("panic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n    "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// Don\'t forget to set the "Content-Type" header!')]),t._v("\n    headers "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("FormDataContentType")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n    resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Post")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/register"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" headers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n        "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("defer")]),t._v(" resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Close")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n        suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Welcome!"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("GetBody")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("resp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("You can write a multi-file upload by calling "),e("code",[t._v("suite.WriteFile")]),t._v(" successively using the same field name.")])]),t._v(" "),e("h2",{attrs:{id:"testing-middleware"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testing-middleware"}},[t._v("#")]),t._v(" Testing middleware")]),t._v(" "),e("p",[t._v("You can unit-test middleware using the "),e("a",{attrs:{href:"#suite-middleware"}},[e("code",[t._v("suite.Middleware")])]),t._v(" function. This function passes a "),e("code",[t._v("*goyave.Request")]),t._v(" to your middlware and returns the "),e("code",[t._v("*http.Response")]),t._v(". This function also takes a test procedure function as a parameter. This function will simulate a "),e("strong",[t._v("controller handler")]),t._v(", so you can test if the middleware alters the request.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("rawRequest "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" httptest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"GET"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/test-route"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrawRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Header"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Set")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"application/json"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrequest "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("CreateTestRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rawRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Data "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"text"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"  \\n  test  \\t"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nresult "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Middleware")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("middleware"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Trim"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"application/json"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Header")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Get")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"test"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("String")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"text"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nsuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusCode"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("If you want to test a blocking middleware, flag the test as failed in the test procedure. Indeed, the procedure shouldn't be executed if your middleware doesn't pass to the next handler.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("request "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("CreateTestRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nsuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Middleware")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("middleware"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Auth"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" request "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("Request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Fail")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Auth middleware passed"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h2",{attrs:{id:"testsuite-reference"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-reference"}},[t._v("#")]),t._v(" TestSuite reference")]),t._v(" "),e("div",{staticClass:"table"},[e("p",[e("a",{attrs:{href:"#testsuite-runserver"}},[t._v("RunServer")]),t._v(" "),e("a",{attrs:{href:"#testsuite-timeout"}},[t._v("Timeout")]),t._v(" "),e("a",{attrs:{href:"#testsuite-settimeout"}},[t._v("SetTimeout")]),t._v(" "),e("a",{attrs:{href:"#testsuite-middleware"}},[t._v("Middleware")]),t._v(" "),e("a",{attrs:{href:"#testsuite-get"}},[t._v("Get")]),t._v(" "),e("a",{attrs:{href:"#testsuite-post"}},[t._v("Post")]),t._v(" "),e("a",{attrs:{href:"#testsuite-put"}},[t._v("Put")]),t._v(" "),e("a",{attrs:{href:"#testsuite-patch"}},[t._v("Patch")]),t._v(" "),e("a",{attrs:{href:"#testsuite-delete"}},[t._v("Delete")]),t._v(" "),e("a",{attrs:{href:"#testsuite-request"}},[t._v("Request")]),t._v(" "),e("a",{attrs:{href:"#testsuite-getbody"}},[t._v("GetBody")]),t._v(" "),e("a",{attrs:{href:"#testsuite-getjsonbody"}},[t._v("GetJSONBody")]),t._v(" "),e("a",{attrs:{href:"#testsuite-createtestfiles"}},[t._v("CreateTestFiles")]),t._v(" "),e("a",{attrs:{href:"#testsuite-createtestrequest"}},[t._v("CreateTestRequest")]),t._v(" "),e("a",{attrs:{href:"#testsuite-createtestresponse"}},[t._v("CreateTestResponse")]),t._v(" "),e("a",{attrs:{href:"#testsuite-createtestresponsewithrequest"}},[t._v("CreateTestResponseWithRequest")]),t._v(" "),e("a",{attrs:{href:"#testsuite-writefile"}},[t._v("WriteFile")]),t._v(" "),e("a",{attrs:{href:"#testsuite-writefield"}},[t._v("WriteField")]),t._v(" "),e("a",{attrs:{href:"#testsuite-cleardatabase"}},[t._v("ClearDatabase")]),t._v(" "),e("a",{attrs:{href:"#testsuite-cleardatabasetables"}},[t._v("ClearDatabaseTables")]),t._v(" "),e("a",{attrs:{href:"#goyave-runtest"}},[t._v("RunTest")])])]),e("h4",{attrs:{id:"testsuite-runserver"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-runserver"}},[t._v("#")]),t._v(" TestSuite.RunServer")]),t._v(" "),e("p",[t._v("RunServer start the application and run the given functional test procedure.")]),t._v(" "),e("p",[t._v("This function is the equivalent of "),e("code",[t._v("goyave.Start()")]),t._v("."),e("br"),t._v("\nThe test fails if the suite's timeout is exceeded."),e("br"),t._v("\nThe server automatically shuts down when the function ends."),e("br"),t._v("\nThis function is synchronized, that means that the server is properly stopped when the function returns.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("routeRegistrer func(*goyave.Router)")])]),t._v(" "),e("td",[e("code",[t._v("void")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("procedure func()")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-timeout"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-timeout"}},[t._v("#")]),t._v(" TestSuite.Timeout")]),t._v(" "),e("p",[t._v("Get the timeout for test failure when using RunServer or requests.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td"),t._v(" "),e("td",[e("code",[t._v("time.Duration")])])])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-settimeout"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-settimeout"}},[t._v("#")]),t._v(" TestSuite.SetTimeout")]),t._v(" "),e("p",[t._v("Set the timeout for test failure when using RunServer or requests.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("time.Duration")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-middleware"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-middleware"}},[t._v("#")]),t._v(" TestSuite.Middleware")]),t._v(" "),e("p",[t._v("Executes the given middleware and returns the HTTP response. Core middleware (recovery, parsing and language) is not executed.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("middleware goyave.Middleware")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("request *goyave.Request")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("procedure goyave.Handler")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-get"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-get"}},[t._v("#")]),t._v(" TestSuite.Get")]),t._v(" "),e("p",[t._v("Execute a GET request on the given route. Headers are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-post"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-post"}},[t._v("#")]),t._v(" TestSuite.Post")]),t._v(" "),e("p",[t._v("Execute a POST request on the given route. Headers and body are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-put"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-put"}},[t._v("#")]),t._v(" TestSuite.Put")]),t._v(" "),e("p",[t._v("Execute a PUT request on the given route. Headers and body are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-patch"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-patch"}},[t._v("#")]),t._v(" TestSuite.Patch")]),t._v(" "),e("p",[t._v("Execute a PATCH request on the given route. Headers and body are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-delete"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-delete"}},[t._v("#")]),t._v(" TestSuite.Delete")]),t._v(" "),e("p",[t._v("Execute a DELETE request on the given route. Headers and body are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-request"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-request"}},[t._v("#")]),t._v(" TestSuite.Request")]),t._v(" "),e("p",[t._v("Execute a request on the given route. Headers and body are optional.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("method string")])]),t._v(" "),e("td",[e("code",[t._v("*http.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("route string")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("headers map[string]string")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("body io.Reader")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-getbody"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-getbody"}},[t._v("#")]),t._v(" TestSuite.GetBody")]),t._v(" "),e("p",[t._v("Read the whole body of a response. If read failed, test fails and return empty byte slice.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("response *http.Response")])]),t._v(" "),e("td",[e("code",[t._v("[]byte")])])])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-getjsonbody"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-getjsonbody"}},[t._v("#")]),t._v(" TestSuite.GetJSONBody")]),t._v(" "),e("p",[t._v("Read the whole body of a response and decode it as JSON. If read or decode failed, test fails. The "),e("code",[t._v("data")]),t._v(" parameter should be a pointer.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("response *http.Response")])]),t._v(" "),e("td",[e("code",[t._v("error")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("data interface{}")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-createtestfiles"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-createtestfiles"}},[t._v("#")]),t._v(" TestSuite.CreateTestFiles")]),t._v(" "),e("p",[t._v("Create a slice of "),e("code",[t._v("filesystem.File")]),t._v(" from the given paths. Files are passed to a temporary http request and parsed as Multipart form, to reproduce the way files are obtained in real scenarios.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("paths ...string")])]),t._v(" "),e("td",[e("code",[t._v("[]filesystem.File")])])])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-createtestrequest"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-createtestrequest"}},[t._v("#")]),t._v(" TestSuite.CreateTestRequest")]),t._v(" "),e("p",[t._v("Create a "),e("code",[t._v("*goyave.Request")]),t._v(" from the given raw request. This function is aimed at making it easier to unit test Requests.")]),t._v(" "),e("p",[t._v("If passed request is "),e("code",[t._v("nil")]),t._v(", a default "),e("code",[t._v("GET")]),t._v(" request to "),e("code",[t._v("/")]),t._v(" is used.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("rawRequest *http.Request")])]),t._v(" "),e("td",[e("code",[t._v("*goyave.Request")])])])])]),t._v(" "),e("p",[e("strong",[t._v("Example:")])]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("rawRequest "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" httptest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"GET"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/test-route"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("nil")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrawRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Header"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Set")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Content-Type"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"application/json"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrequest "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("CreateTestRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rawRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Lang "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"en-US"')]),t._v("\nrequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Data "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("map")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("string")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"field"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"value"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h4",{attrs:{id:"testsuite-createtestresponse"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-createtestresponse"}},[t._v("#")]),t._v(" TestSuite.CreateTestResponse")]),t._v(" "),e("p",[t._v("Create an empty response with the given response writer. This function is aimed at making it easier to unit test Responses.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("recorder http.ResponseWriter")])]),t._v(" "),e("td",[e("code",[t._v("*goyave.Response")])])])])]),t._v(" "),e("p",[e("strong",[t._v("Example:")])]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("writer "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" httptest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewRecorder")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresponse "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("CreateTestResponse")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresponse"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Status")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("http"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusNoContent"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Result")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nfmt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Println")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusCode"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 204")]),t._v("\n")])])]),e("h4",{attrs:{id:"testsuite-createtestresponsewithrequest"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-createtestresponsewithrequest"}},[t._v("#")]),t._v(" TestSuite.CreateTestResponseWithRequest")]),t._v(" "),e("p",[t._v("Create an empty response with the given response writer and HTTP request. This function is aimed at making it easier to unit test Responses needing the raw request's information, such as redirects.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("recorder http.ResponseWriter")])]),t._v(" "),e("td",[e("code",[t._v("*goyave.Response")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("rawRequest *http.Request")])]),t._v(" "),e("td")])])]),t._v(" "),e("p",[e("strong",[t._v("Example:")])]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("writer "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" httptest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewRecorder")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nrawRequest "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" httptest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"POST"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/test-route"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" strings"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewReader")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"body"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresponse "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("CreateTestResponseWithRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rawRequest"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresponse"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Status")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("http"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusNoContent"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nresult "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" writer"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Result")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\nfmt"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Println")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("StatusCode"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 204")]),t._v("\n")])])]),e("h4",{attrs:{id:"testsuite-writefile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-writefile"}},[t._v("#")]),t._v(" TestSuite.WriteFile")]),t._v(" "),e("p",[t._v("Write a file to the given writer. This function is handy for file upload testing. The test fails if an error occurred.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("write *multipart.Writer")])]),t._v(" "),e("td",[e("code",[t._v("void")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("path string")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("fieldName string")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("fileName string")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-writefield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-writefield"}},[t._v("#")]),t._v(" TestSuite.WriteField")]),t._v(" "),e("p",[t._v("Create and write a new multipart form field. The test fails if the field couldn't be written.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("write *multipart.Writer")])]),t._v(" "),e("td",[e("code",[t._v("void")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("fieldName string")])]),t._v(" "),e("td")]),t._v(" "),e("tr",[e("td",[e("code",[t._v("value string")])]),t._v(" "),e("td")])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-cleardatabase"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-cleardatabase"}},[t._v("#")]),t._v(" TestSuite.ClearDatabase")]),t._v(" "),e("p",[t._v("Delete all records in all tables. This function only clears the tables of registered models.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td"),t._v(" "),e("td",[e("code",[t._v("void")])])])])]),t._v(" "),e("h4",{attrs:{id:"testsuite-cleardatabasetables"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#testsuite-cleardatabasetables"}},[t._v("#")]),t._v(" TestSuite.ClearDatabaseTables")]),t._v(" "),e("p",[t._v("Drop all tables. This function only clears the tables of registered models.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td"),t._v(" "),e("td",[e("code",[t._v("void")])])])])]),t._v(" "),e("h4",{attrs:{id:"goyave-runtest"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#goyave-runtest"}},[t._v("#")]),t._v(" goyave.RunTest")]),t._v(" "),e("p",[t._v('Run a test suite with prior initialization of a test environment. The GOYAVE_ENV environment variable is automatically set to "test" and restored to its original value at the end of the test run.')]),t._v(" "),e("p",[t._v("All tests are run using your project's root as working directory. This directory is determined by the presence of a "),e("code",[t._v("go.mod")]),t._v(" file.")]),t._v(" "),e("p",[t._v("The function returns true if the test passed.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("t *testing.T")])]),t._v(" "),e("td",[e("code",[t._v("bool")])])]),t._v(" "),e("tr",[e("td",[e("code",[t._v("suite ITestSuite")])]),t._v(" "),e("td")])])]),t._v(" "),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[e("code",[t._v("ITestSuite")]),t._v(" is the interface "),e("code",[t._v("TestSuite")]),t._v(" is implementing.")])]),t._v(" "),e("h2",{attrs:{id:"database-testing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#database-testing"}},[t._v("#")]),t._v(" Database testing")]),t._v(" "),e("p",[t._v("You may need to test features interacting with your database. Goyave provides a handy way to generate and save records in your database: "),e("strong",[t._v("factories")]),t._v(".")]),t._v(" "),e("p",[e("strong",[t._v("All registered models records are automatically deleted from the database when each test suite completes.")])]),t._v(" "),e("p",[t._v("It is a good practice to use a separate database dedicated for testing, named "),e("code",[t._v("myapp_test")]),t._v(" for example. Don't forget to change the database information in your "),e("code",[t._v("config.test.json")]),t._v(" file.")]),t._v(" "),e("p",[t._v("All functions below require the "),e("code",[t._v("database")]),t._v("package to be imported.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"github.com/System-Glitch/goyave/v2/database"')]),t._v("\n")])])]),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("p",[t._v("You may want to use a clean database for each of your tests. You can clear your database before each test using "),e("a",{attrs:{href:"https://pkg.go.dev/github.com/stretchr/testify/suite?tab=doc#SetupTestSuite",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("suite.SetupTest()")]),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),t._v("CustomTestSuite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetupTest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    suite"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("ClearDatabase")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])]),t._v(" "),e("h3",{attrs:{id:"generators"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#generators"}},[t._v("#")]),t._v(" Generators")]),t._v(" "),e("p",[t._v("Factories need a "),e("strong",[t._v("generator function")]),t._v(". These functions generate a single random record. You can use the faking library of your choice, but in this example we are going to use "),e("a",{attrs:{href:"https://github.com/bxcodec/faker",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("github.com/bxcodec/faker")]),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"github.com/bxcodec/faker/v3"')]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("UserGenerator")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    user "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("User"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n    user"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Name "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" faker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Name")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n    faker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetGenerateUniqueValues")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    user"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Email "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" faker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Email")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    faker"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("SetGenerateUniqueValues")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" user\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("div",{staticClass:"custom-block tip"},[e("p",{staticClass:"custom-block-title"},[t._v("TIP")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("database.Generator")]),t._v(" is an alias for "),e("code",[t._v("func() interface{}")]),t._v(".")]),t._v(" "),e("li",[t._v("Generator functions should be declared in the same file as the model it is generating.")])])]),t._v(" "),e("p",[t._v("Generators can also create associated records. Associated records should be generated using their respective generators. In the following example, we are generating users for an application allowing users to write blog posts.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("UserGenerator")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("interface")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    user "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("User"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... Generate users fields ...")]),t._v("\n\n    "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate between 0 and 10 blog posts")]),t._v("\n    rand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Seed")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("time"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Now")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("UnixNano")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    user"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Posts "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" database"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewFactory")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("PostGenerator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Generate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("rand"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Intn")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n    "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" user\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"using-factories"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#using-factories"}},[t._v("#")]),t._v(" Using factories")]),t._v(" "),e("p",[t._v("You can create a factory from any "),e("code",[t._v("database.Generator")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("factory "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" database"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewFactory")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("model"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("UserGenerator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate 5 random users")]),t._v("\nrecords "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" factory"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Generate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Generate and insert 5 random users into the database")]),t._v("\ninsertedRecords "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" factory"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Save")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("Note that generated records will not have an ID if they are not inserted into the database.")]),t._v(" "),e("p",[t._v("Associated records created by the generator will also be inserted on "),e("code",[t._v("factory.Save")]),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"overrides"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#overrides"}},[t._v("#")]),t._v(" Overrides")]),t._v(" "),e("p",[t._v("It is possible to override some of the generated data if needed, for example if you need to test the behavior of a function with a specific value. All generated structures will be merged with the override.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[t._v("override "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("model"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("User"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    Name"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Jérémy"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nrecords "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":=")]),t._v(" factory"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Override")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("override"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Generate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// All generated records will have the same name: "Jérémy"')]),t._v("\n")])])]),e("div",{staticClass:"custom-block warning"},[e("p",{staticClass:"custom-block-title"},[t._v("WARNING")]),t._v(" "),e("p",[t._v("Overrides must be of the "),e("strong",[t._v("same type")]),t._v(" as the generated record.")])]),t._v(" "),e("h4",{attrs:{id:"factory-reference"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#factory-reference"}},[t._v("#")]),t._v(" Factory reference")]),t._v(" "),e("div",{staticClass:"table"},[e("p",[e("a",{attrs:{href:"#database-newfactory"}},[t._v("NewFactory")]),t._v(" "),e("a",{attrs:{href:"#factory-override"}},[t._v("Override")])])]),e("h4",{attrs:{id:"database-newfactory"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#database-newfactory"}},[t._v("#")]),t._v(" database.NewFactory")]),t._v(" "),e("p",[t._v("Create a new Factory. The given generator function will be used to generate records.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("generator database.Generator")])]),t._v(" "),e("td",[e("code",[t._v("database.Factory")])])])])]),t._v(" "),e("h4",{attrs:{id:"factory-override"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#factory-override"}},[t._v("#")]),t._v(" Factory.Override")]),t._v(" "),e("p",[t._v("Set an override model for generated records. Values present in the override model will replace the ones in the generated records. This function expects a struct "),e("strong",[t._v("pointer")]),t._v(" as parameter. This function returns the same instance of "),e("code",[t._v("Factory")]),t._v(" so this method can be chained.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("override interface{}")])]),t._v(" "),e("td",[e("code",[t._v("database.Factory")])])])])]),t._v(" "),e("h4",{attrs:{id:"factory-generate"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#factory-generate"}},[t._v("#")]),t._v(" Factory.Generate")]),t._v(" "),e("p",[t._v("Generate a number of records using the given factory.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("count uint")])]),t._v(" "),e("td",[e("code",[t._v("[]interface{}")])])])])]),t._v(" "),e("h4",{attrs:{id:"factory-save"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#factory-save"}},[t._v("#")]),t._v(" Factory.Save")]),t._v(" "),e("p",[t._v("Generate a number of records using the given factory and return the inserted records.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",[t._v("Parameters")]),t._v(" "),e("th",[t._v("Return")])])]),t._v(" "),e("tbody",[e("tr",[e("td",[e("code",[t._v("count uint")])]),t._v(" "),e("td",[e("code",[t._v("[]interface{}")])])])])]),t._v(" "),e("h3",{attrs:{id:"seeders"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeders"}},[t._v("#")]),t._v(" Seeders")]),t._v(" "),e("p",[t._v("Seeders are functions which create a number of random records in the database in order to create a full and realistic test environment. Seeders are written in the "),e("code",[t._v("database/seeder")]),t._v(" package.")]),t._v(" "),e("p",[t._v("Each seeder should have its own file. A seeder's responsibilities are limited to a single table or model. For example, the "),e("code",[t._v("seeder.User")]),t._v(" should only seed the "),e("code",[t._v("users")]),t._v(" table. Moreover, seeders should have the same name as the model they are using.")]),t._v(" "),e("div",{staticClass:"language-go extra-class"},[e("pre",{pre:!0,attrs:{class:"language-go"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("package")]),t._v(" seeder\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"my-project/database/model"')]),t._v("\n    "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"github.com/System-Glitch/goyave/v2/database"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("func")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("User")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    database"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("NewFactory")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("model"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("UserGenerator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Save")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]);