I'm setting service_test.go for service.go.
In service.go, method is called from dao.go.
So I need to mock this dao method.
But I'm not sure how to code this mock method.
Here is the repository structure.
article
├ client
├ api
│ ├ main.go
│ ├ contoroller
│ │ └ contoroller.go
│ ├ service
│ │ └ service.go
│ ├ dao
│ │ └ dao.go
│ ├ go.mod
│ ├ go.sum
│ └ Dockerfile
├ nginx
└ docker-compose.yml
service.go
func GetArticleService(db *sql.DB) []util.Article {
var articles []util.Article
// I want to mock dao.GetArticleDao(db)
results := dao.GetArticleDao(db)
article := util.Article{}
for results.Next() {
err := results.Scan(&article.ID, &article.UUID, &article.TITLE, &article.CONTENT)
if err != nil {
panic(err.Error())
} else {
articles = append(articles, article)
}
}
return articles
}
service_test.go
func TestGetArticleService(t *testing.T) {
//mock db
db, _, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
//make expected value
var expectedArticles []util.Article
expectedArticle1 := util.Article{
ID: 1,
UUID: "bea1b24d-0627-4ea0-aa2b-8af4c6c2a41c",
TITLE: "test",
CONTENT: "test",
}
expectedArticles = append(expectedArticles, expectedArticle1)
expectedArticle2 := util.Article{
ID: 2,
UUID: "844bc620-7336-41a3-9cb4-552a0024ff1c",
TITLE: "test2",
CONTENT: "test2",
}
expectedArticles = append(expectedArticles, expectedArticle2)
//check whether expected value and GetArticleService(db) is equal.
//Since GetArticleService(db) is executed, I want to mock dao.GetArticleDao(db)
assert.Equal(t, expectedArticles, GetArticleService(db))
}
I want to mock dao.GetArticleDao(db) in service.go to pass test in service_test.go.
But I'm not sure how to mock this code.
So to do this, you need to be a little more abstract with you definition of the actual code, this allows you to replace the call to a third party module for testing.
Something like below will allow you to swap out the dao function for a testing mock function that has the same signature. As soon as you define a hard type or function call you tie yourself that function/type permanently.
func GetArticleService(getArticleDao func(*sql.DB) (string), db *sql.DB) []util.Article {
var articles []util.Article
// this is the mock, at this point you can pass in a mock function for testing
results := getArticleDao(db)
article := util.Article{}
for results.Next() {
err := results.Scan(&article.ID, &article.UUID, &article.TITLE, &article.CONTENT)
if err != nil {
panic(err.Error())
} else {
articles = append(articles, article)
}
}
return articles
}
Related
Below is my code for main.go
func main() {
app := fiber.New()
app.Use(recover.New())
inferenceController := controllers.InferenceController
middleware := middleware.Middleware
privateRoutes := routes.PrivateRoutes{InferenceController: inferenceController,Middleware: middleware }
privateRoutes.Routes(app)
log.Fatal(app.Listen(":3000"))
}
I am trying to test this code but can't figure out the way for testing
In your test you actually need to create the app and register the relevent handlers. Then use app.Test() to call the handler. You can create body content as needed and check response codes and body content.
In this model you setup your server with just the endpoints/middleware you need for each test case. You can provide mock's around this if you need, depending on your specific use case.
For your example above, it would be something like the below, not knowing what your actual endpoints are:
func TestMyFiberEndpoiunt(t *testing.T) {
// Setup the app
app := Fiber.New()
app.Use(recover.New())
inferenceController := controllers.InferenceController
middleware := middleware.Middleware
privateRoutes := routes.PrivateRoutes{InferenceController: inferenceController,Middleware: middleware }
privateRoutes.Routes(app)
// Setup your request body
reqBody := ReqData{ SomeData: "something" }
bodyJson, _ := json.Marshal(&reqBody)
req := httptest.NewRequest("GET", "/api/v1/endpoint", bytes.NewReader(bodyJson))
resp, _ := app.Test(req, 10)
// Check the expected response code
assert.Equal(t, 200, resp.StatusCode)
// Check the body content
respBody := make(byte, resp.ContentLength)
_, _ = resp.Body.read(respBody)
assert.Equal(t, `{"data":"expected"}`, string(respBody))
}
If you need stateful data accross multiple tests for some use case, you could setup your server in a TestMain with all the needed routes and share it as a package var.
If the data marshalling seems like a lot of overhead for each test case, you can use a helper function such as:
func GetJsonTestRequestResponse(app *fiber.App, method string, url string, reqBody any) (code int, respBody map[string]any, err error) {
bodyJson := []byte("")
if reqBody != nil {
bodyJson, _ := json.Marshal(reqBody)
}
req := httptest.NewRequest(method, url, bytes.NewReader(bodyJson))
resp, err := app.Test(req, 10)
code = resp.StatusCode
// If error we're done
if err != nil {
return
}
// If no body content, we're done
if resp.ContentLength == 0 {
return
}
bodyData := make([]byte, resp.ContentLength)
_, _ = resp.Body.Read(bodyData)
err = json.Unmarshal(bodyData, &respBody)
return
}
Then tests cases look cleaner and are easier to write (imho).
type testArg struct {
Arg1 string
Arg2 int
}
func TestMyFakeEndpoint(t *testing.T) {
app := fiber.New()
defer app.Shutdown()
app.Post("/test", func(c *fiber.Ctx) error {
arg := testArg{}
_ = json.Unmarshal(c.Request().Body(), &arg)
return c.JSON(arg)
})
code, body, err := GetJsonTestRequestResponse(app, "POST", "/test", testArg{"testing", 123})
assert.Nil(t, err)
assert.Equal(t, 200, code)
assert.EqualValues(t, body["Arg1"], "testing")
assert.EqualValues(t, body["Arg2"], 123)
}
Looking at the set up for go-vcr
// Start our recorder
r, err := recorder.New("fixtures/etcd")
if err != nil {
log.Fatal(err)
}
defer r.Stop() // Make sure recorder is stopped once done with it
// Create an etcd configuration using our transport
cfg := client.Config{
Endpoints: []string{"http://127.0.0.1:2379"},
HeaderTimeoutPerRequest: time.Second,
Transport: r, // Inject as transport!
}
Attempting to use this library using the githubv4 library seems at though it needs a way to handle Oauth
import "golang.org/x/oauth2"
func main() {
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: os.Getenv("GITHUB_TOKEN")},
)
httpClient := oauth2.NewClient(context.Background(), src)
client := githubv4.NewClient(httpClient)
// Use client...
}
I'm not sure how to get the recorder 'r' into the oauth2 client. If at all possible.
Has anyone been successful with this? I've tried passing in a httpClient with the 'r' recorder but it ends up as a 401 - looks like this default client can't do the Oauth dance.
I'd like to use the GraphQL API but can fall back to the REST API if is is easier but I just want to make sure this isn't really possible. Has anyone else been successful with this?
This issue resolved this question for me.
https://github.com/dnaeon/go-vcr/issues/59
Example below
package example_test
import (
"context"
"github.com/dnaeon/go-vcr/cassette"
"github.com/dnaeon/go-vcr/recorder"
"github.com/google/go-github/v33/github"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
"net/http"
"path"
"testing"
)
func TestGithub(t *testing.T) {
//custom http.Transport, since github uses oauth2 authentication
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: "YOUR_GITHUB_TOKEN"},
)
tr := &oauth2.Transport{
Base: http.DefaultTransport,
Source: oauth2.ReuseTokenSource(nil, ts),
}
// Start our recorder
vcrRecorder, err := recorder.NewAsMode(path.Join("testdata", "fixtures", t.Name()), recorder.ModeRecording, tr)
require.NoError(t, err)
defer vcrRecorder.Stop() // NEWLY ADDED CODE HERE
// Filter out dynamic & sensitive data/headers
// Your test code will continue to see the real access token and
// it is redacted before the recorded interactions are saved
// =====> commenting out this section has no impact on missing recording
vcrRecorder.AddSaveFilter(func(i *cassette.Interaction) error {
delete(i.Request.Headers, "Authorization")
delete(i.Request.Headers, "User-Agent")
i.Request.Headers["Authorization"] = []string{"Basic UExBQ0VIT0xERVI6UExBQ0VIT0xERVI="} //PLACEHOLDER:PLACEHOLDER
return nil
})
// custom http.client
httpClient := &http.Client{
Transport: vcrRecorder,
}
ghClient := github.NewClient(httpClient)
// =====> actual test, should create cassettes, but does not.
_, _, err = ghClient.Users.Get(context.Background(), "")
require.NoError(t, err)
}
My project is split into three main components: controllers, services, and models. When a route is queried via the URI, the controllers are called, which then call the services to interact with the models, which then interact with the database via gorm.
I am trying to write unit tests for the controllers, but I'm having a hard time understanding how to properly mock the services layer while mocking the gin layer. I can get a mocked gin context, but I'm not able to mock the service layer within my controller method. Below is my code:
resourceController.go
package controllers
import (
"MyApi/models"
"MyApi/services"
"github.com/gin-gonic/gin"
"net/http"
)
func GetResourceById(c *gin.Context) {
id := c.Param("id")
resource, err := services.GetResourceById(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"status": http.StatusBadRequest, "message": err})
return
} else if resource.ID == 0 {
c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "Resource with id:"+id+" does not exist"})
return
}
c.JSON(http.StatusOK, gin.H{
"id": resource.ID,
"data1": resource.Data1,
"data2": resource.Data2,
})
}
I want to test that the c.JSON is returning with the proper http status and other data. I need to mock the id variable, err variable, and c.JSON function, but when I try to set the c.JSON function in the test to my new function, I get an error saying Cannot assign to c.JSON.
Below is my attempt at writing a test:
resourceController_test.go
package controllers
import (
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"net/http/httptest"
"testing"
)
func TestGetResourceById(t *testing.T) {
var status int
var body interface{}
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.JSON = func(stat int, object interface{}) {
status = stat
body = object
}
GetResourceById(c)
assert.Equal(t, 4, 4)
}
How do I properly write a unit test to test whether the c.JSON is returning the proper values?
You cannot modify a method of a type in Go. It is defined and immuatable by the package that defines the type at compile time. This is a design decision by Go. Simply don't do it.
You have already use httptest.NewRecorder() as a mock of gin.Context.ResponseWriter, which will records what is written to the response, including the c.JSON call. However, you need to keep a reference of the httptest.ReponseRecorder and then check it later. Note that you only have a marshalled JSON, so you need to unmarshal it to check content (as both Go map and JSON objects's order does not matter, checking marshalled string's equality is error-prone).
For example,
func TestGetResourceById(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
GetResourceById(c)
assert.Equal(t, 200, w.Code) // or what value you need it to be
var got gin.H
err := json.Unmarshal(w.Body.Bytes(), &got)
if err != nil {
t.Fatal(err)
}
assert.Equal(t, want, got) // want is a gin.H that contains the wanted map.
}
Based on the testing section, you can do something like:
func TestGetResourceById(t *testing.T) {
router := setupRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/GetResourceById", nil)
router.ServeHTTP(w, req)
assert.Equal(t, 200, w.Code)
assert.Equal(t, "your expected output", w.Body.String())
}
I'm writing a REST API using Gin framework. But I was faced a trouble testing my controllers and researching TDD and Mock. I tried to apply TDD and Mock to my code but I could not.
I created a very reduced test environment and tried to create a controller test. How do I create a Mock for Gin.Context?
Here's my example code:
package main
import (
"strconv"
"github.com/gin-gonic/gin"
)
// MODELS
type Users []User
type User struct {
Name string `json"name"`
}
func main() {
r := gin.Default()
r.GET("/users", GetUsers)
r.GET("/users/:id", GetUser)
r.Run(":8080")
}
// ROUTES
func GetUsers(c *gin.Context) {
repo := UserRepository{}
ctrl := UserController{}
ctrl.GetAll(c, repo)
}
func GetUser(c *gin.Context) {
repo := UserRepository{}
ctrl := UserController{}
ctrl.Get(c, repo)
}
// CONTROLLER
type UserController struct{}
func (ctrl UserController) GetAll(c *gin.Context, repository UserRepositoryIterface) {
c.JSON(200, repository.GetAll())
}
func (ctrl UserController) Get(c *gin.Context, repository UserRepositoryIterface) {
id := c.Param("id")
idConv, _ := strconv.Atoi(id)
c.JSON(200, repository.Get(idConv))
}
// REPOSITORY
type UserRepository struct{}
type UserRepositoryIterface interface {
GetAll() Users
Get(id int) User
}
func (r UserRepository) GetAll() Users {
users := Users{
{Name : "Wilson"},
{Name : "Panda"},
}
return users
}
func (r UserRepository) Get(id int) User {
users := Users{
{Name : "Wilson"},
{Name : "Panda"},
}
return users[id-1]
}
My test example:
package main
import(
"testing"
_ "github.com/gin-gonic/gin"
)
type UserRepositoryMock struct{}
func (r UserRepositoryMock) GetAll() Users {
users := Users{
{Name : "Wilson"},
{Name : "Panda"},
}
return users
}
func (r UserRepositoryMock) Get(id int) User {
users := Users{
{Name : "Wilson"},
{Name : "Panda"},
}
return users[id-1]
}
// TESTING REPOSITORY FUNCTIONS
func TestRepoGetAll(t *testing.T) {
userRepo := UserRepository{}
amountUsers := len(userRepo.GetAll())
if amountUsers != 2 {
t.Errorf("Esperado %d, recebido %d", 2, amountUsers)
}
}
func TestRepoGet(t *testing.T) {
expectedUser := struct{
Name string
}{
"Wilson",
}
userRepo := UserRepository{}
user := userRepo.Get(1)
if user.Name != expectedUser.Name {
t.Errorf("Esperado %s, recebido %s", expectedUser.Name, user.Name)
}
}
/* HOW TO TEST CONTROLLER?
func TestControllerGetAll(t *testing.T) {
gin.SetMode(gin.TestMode)
c := &gin.Context{}
c.Status(200)
repo := UserRepositoryMock{}
ctrl := UserController{}
ctrl.GetAll(c, repo)
}
*/
Gin provides the option to create a Test Context which you can use for whatever you need:
https://godoc.org/github.com/gin-gonic/gin#CreateTestContext
Like that:
c, _ := gin.CreateTestContext(httptest.NewRecorder())
Here is an example of how I mock a context, add a param, use it in a function, then print the string of the response if there was a non-200 response.
gin.SetMode(gin.TestMode)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
c.Params = []gin.Param{gin.Param{Key: "k", Value: "v"}}
foo(c)
if w.Code != 200 {
b, _ := ioutil.ReadAll(w.Body)
t.Error(w.Code, string(b))
}
In order to get a *gin.Context instance that you can test, you need a mock HTTP request and response. An easy way to create those is to use the net/http and net/http/httptest packages. Based on the code you linked, your test would look like this:
package main
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func TestControllerGetAll(t *testing.T) {
// Switch to test mode so you don't get such noisy output
gin.SetMode(gin.TestMode)
// Setup your router, just like you did in your main function, and
// register your routes
r := gin.Default()
r.GET("/users", GetUsers)
// Create the mock request you'd like to test. Make sure the second argument
// here is the same as one of the routes you defined in the router setup
// block!
req, err := http.NewRequest(http.MethodGet, "/users", nil)
if err != nil {
t.Fatalf("Couldn't create request: %v\n", err)
}
// Create a response recorder so you can inspect the response
w := httptest.NewRecorder()
// Perform the request
r.ServeHTTP(w, req)
// Check to see if the response was what you expected
if w.Code != http.StatusOK {
t.Fatalf("Expected to get status %d but instead got %d\n", http.StatusOK, w.Code)
}
}
Although you could create a mock *gin.Context, it's probably easier to use the method above, since it'll execute and handle your request the same as it would an actual request.
If to reduce the question to "How to create mock for a function argument?" the answer is: use interfaces not concrete types.
type Context struct is a concrete type literal and Gin doesn't provide appropriate interface. But you can declare it by yourself. Since you are using only JSON method from Context you can declare extra-simple interface:
type JSONer interface {
JSON(code int, obj interface{})
}
And use JSONer type instead Context type in all your functions which expect Context as argument:
/* Note, you can't declare argument as a pointer to interface type,
but when you call it you can pass pointer to type which
implements the interface.*/
func GetUsers(c JSONer) {
repo := UserRepository{}
ctrl := UserController{}
ctrl.GetAll(c, repo)
}
func GetUser(c JSONer) {
repo := UserRepository{}
ctrl := UserController{}
ctrl.Get(c, repo)
}
func (ctrl UserController) GetAll(c JSONer, repository UserRepositoryIterface) {
c.JSON(200, repository.GetAll())
}
func (ctrl UserController) Get(c JSONer, repository UserRepositoryIterface) {
id := c.Param("id")
idConv, _ := strconv.Atoi(id)
c.JSON(200, repository.Get(idConv))
}
And now it is easy to test
type ContextMock struct {
JSONCalled bool
}
func (c *ContextMock) JSON(code int, obj interface{}){
c.JSONCalled = true
}
func TestControllerGetAll(t *testing.T) {
gin.SetMode(gin.TestMode)
c := &ContextMock{false}
c.Status(200)
repo := UserRepositoryMock{}
ctrl := UserController{}
ctrl.GetAll(c, repo)
if c.JSONCalled == false {
t.Fail()
}
}
Example simple as possible.
There is another question with a close sense
I've built a quick and easy API in Go that queries ElasticSearch. Now that I know it can be done, I want to do it correctly by adding tests. I've abstracted some of my code so that it can be unit-testable, but I've been having some issues mocking the elastic library, and as such I figured it would be best if I tried a simple case to mock just that.
import (
"encoding/json"
"github.com/olivere/elastic"
"net/http"
)
...
func CheckBucketExists(name string, client *elastic.Client) bool {
exists, err := client.IndexExists(name).Do()
if err != nil {
panic(err)
}
return exists
}
And now the test...
import (
"fmt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"testing"
)
type MockClient struct {
mock.Mock
}
func (m *MockClient) IndexExists(name string) (bool, error) {
args := m.Mock.Called()
fmt.Println("This is a thing")
return args.Bool(0), args.Error(1)
}
func TestMockBucketExists(t *testing.T) {
m := MockClient{}
m.On("IndexExists", "thisuri").Return(true)
>> r := CheckBucketExists("thisuri", m)
assert := assert.New(t)
assert.True(r, true)
}
To which I'm yielded with the following error: cannot use m (type MockClient) as type *elastic.Client in argument to CheckBucketExists.
I'm assuming this is something fundamental with my use of the elastic.client type, but I'm still too much of a noob.
This is an old question, but couldn't find the solution either.
Unfortunately, this library is implemented using a struct, that makes mocking it not trivial at all, so the options I found are:
(1) Wrap all the elastic.SearchResult Methods on an interface on your own and "proxy" the call, so you end up with something like:
type ObjectsearchESClient interface {
// ... all methods...
Do(context.Context) (*elastic.SearchResult, error)
}
// NewObjectsearchESClient returns a new implementation of ObjectsearchESClient
func NewObjectsearchESClient(cluster *config.ESCluster) (ObjectsearchESClient, error) {
esClient, err := newESClient(cluster)
if err != nil {
return nil, err
}
newClient := objectsearchESClient{
Client: esClient,
}
return &newClient, nil
}
// ... all methods...
func (oc *objectsearchESClient) Do(ctx context.Context) (*elastic.SearchResult, error) {
return oc.searchService.Do(ctx)
}
And then mock this interface and responses as you would with other modules of your app.
(2) Another option is like pointed in this blog post that is mock the response from the Rest calls using httptest.Server
for this, I mocked the handler, that consist of mocking the response from the "HTTP call"
func mockHandler () http.HandlerFunc{
return func(w http.ResponseWriter, r *http.Request) {
resp := `{
"took": 73,
"timed_out": false,
... json ...
"hits": [... ]
...json ... ,
"aggregations": { ... }
}`
w.Write([]byte(resp))
}
}
Then you create a dummy elastic.Client struct
func mockClient(url string) (*elastic.Client, error) {
client, err := elastic.NewSimpleClient(elastic.SetURL(url))
if err != nil {
return nil, err
}
return client, nil
}
In this case, I've a library that builds my elastic.SearchService and returns it, so I use the HTTP like:
...
ts := httptest.NewServer(mockHandler())
defer ts.Close()
esClient, err := mockClient(ts.URL)
ss := elastic.NewSearchService(esClient)
mockLibESClient := es_mock.NewMockSearcherClient(mockCtrl)
mockLibESClient.EXPECT().GetEmployeeSearchServices(ctx).Return(ss, nil)
where mockLibESClient is the library I mentioned, and we stub the mockLibESClient.GetEmployeeSearchServices method making it return the SearchService with that will return the expected payload.
Note: for creating the mock mockLibESClient I used https://github.com/golang/mock
I found this to be convoluted, but "Wrapping" the elastic.Client was in my point of view more work.
Question: I tried to mock it by using https://github.com/vburenin/ifacemaker to create an interface, and then mock that interface with https://github.com/golang/mock and kind of use it, but I kept getting compatibility errors when trying to return an interface instead of a struct, I'm not a Go expect at all so probably I needed to understand the typecasting a little better to be able to solve it like that. So if any of you know how to do it with that please let me know.
The elasticsearch go client Github repo contains an official example of how to mock the elasticsearch client. It basically involves calling NewClient with a configuration which stubs the HTTP transport:
client, err := elasticsearch.NewClient(elasticsearch.Config{
Transport: &mocktrans,
})
There are primarily three ways I discovered to create a Mock/Dumy ES client. My response does not include integration tests against a real Elasticsearch cluster.
You can follow this article so as to mock the response from the Rest calls using httptest.Server, to eventually create a dummy elastic.Client struct
As mentioned by the package author in this link, you can work on "specifying an interface that has two implementations: One that uses a real ES cluster, and one that uses callbacks used in testing. Here's an example to get you started:"
type Searcher interface {
Search(context.Context, SearchRequest) (*SearchResponse, error)
}
// ESSearcher will be used with a real ES cluster.
type ESSearcher struct {
client *elastic.Client
}
func (s *ESSearcher) Search(ctx context.Context, req SearchRequest) (*SearchResponse, error) {
// Use s.client to run against real ES cluster and perform a search
}
// MockedSearcher can be used in testing.
type MockedSearcher struct {
OnSearch func(context.Context, SearchRequest) (*SearchResponse, error)
}
func (s *ESSearcher) Search(ctx context.Context, req SearchRequest) (*SearchResponse, error) {
return s.OnSearch(ctx, req)
}
Finally, as mentioned by the author in the same link you can "run a real Elasticsearch cluster while testing. One particular nice way might be to start the ES cluster during testing with something like github.com/ory/dockertest. Here's an example to get you started:"
package search
import (
"context"
"fmt"
"log"
"os"
"testing"
"github.com/olivere/elastic/v7"
"github.com/ory/dockertest/v3"
"github.com/ory/dockertest/v3/docker"
)
// client will be initialize in TestMain
var client *elastic.Client
func TestMain(m *testing.M) {
pool, err := dockertest.NewPool("")
if err != nil {
log.Fatalf("unable to create new pool: %v", err)
}
options := &dockertest.RunOptions{
Repository: "docker.elastic.co/elasticsearch/elasticsearch-oss",
Tag: "7.8.0",
PortBindings: map[docker.Port][]docker.PortBinding{
"9200": {{HostPort: "9200"}},
},
Env: []string{
"cluster.name=elasticsearch",
"bootstrap.memory_lock=true",
"discovery.type=single-node",
"network.publish_host=127.0.0.1",
"logger.org.elasticsearch=warn",
"ES_JAVA_OPTS=-Xms1g -Xmx1g",
},
}
resource, err := pool.RunWithOptions(options)
if err != nil {
log.Fatalf("unable to ES: %v", err)
}
endpoint := fmt.Sprintf("http://127.0.0.1:%s", resource.GetPort("9200/tcp"))
if err := pool.Retry(func() error {
var err error
client, err = elastic.NewClient(
elastic.SetURL(endpoint),
elastic.SetSniff(false),
elastic.SetHealthcheck(false),
)
if err != nil {
return err
}
_, _, err = client.Ping(endpoint).Do(context.Background())
if err != nil {
return err
}
return nil
}); err != nil {
log.Fatalf("unable to connect to ES: %v", err)
}
code := m.Run()
if err := pool.Purge(resource); err != nil {
log.Fatalf("unable to stop ES: %v", err)
}
os.Exit(code)
}
func TestAgainstRealCluster(t *testing.T) {
// You can use "client" variable here
// Example code:
exists, err := client.IndexExists("cities-test").Do(context.Background())
if err != nil {
t.Fatal(err)
}
if !exists {
t.Fatal("expected to find ES index")
}
}
The line
func CheckBucketExists(name string, client *elastic.Client) bool {
states that CheckBucketExists expects a *elastic.Client.
The lines:
m := MockClient{}
m.On("IndexExists", "thisuri").Return(true)
r := CheckBucketExists("thisuri", m)
pass a MockClient to the CheckBucketExists function.
This is causing a type conflict.
Perhaps you need to import github.com/olivere/elastic into your test file and do:
m := &elastic.Client{}
instead of
m := MockClient{}
But I'm not 100% sure what you're trying to do.