0

I'm setting unit test for api(golang).
I try to set mocking, but there is compile error.
I want to resolve this error to run test.

article
  ├ client
  ├ api
  │  ├ main.go
  │  ├ contoroller
  │  │    ├ contoroller.go
  │  │    └ contoroller_test.go
  │  ├ service
  │  │    ├ service.go
  │  │    └ service_test.go
  │  ├ dao
  │  │    ├ dao.go
  │  │    └ dao_test.go
  │  ├ s3
  │  │    ├ s3.go
  │  │    └ s3_test.go
  │  ├ go.mod 
  │  ├ go.sum
  │  └ Dockerfile
  ├ nginx
  └ docker-compose.yml

Now I'm trying to set dao_test.go.
But compile error occurs in dao_test.go at SetupTest().

dao_test.go

package dao

//import

type MockDaoInterface struct {
}

func (_m *MockDaoInterface) DeleteS3Image(imageName util.ImageName) error {
    return nil
}

type DaoSuite struct {
    suite.Suite
    db   *sql.DB
    mock sqlmock.Sqlmock
    s3   s3.DaoInterface
    dao  *Dao
}

func (s *DaoSuite) SetupTest() {

    var err error
    s.db, s.mock, err = sqlmock.New()
    s.Require().NoError(err)
    s.dao = NewDao(s.db, s.s3)

    // here error occurs 
    s.dao.s3 = MockDaoInterface{}
}

func (s *DaoSuite) TestDeleteArticleDao() {

    // some codes

    s.dao.DeleteArticleDao("1")

}

dao.go

package dao

// import

type Dao struct {
    database *sql.DB
    s3       s3.DaoInterface
}

func NewDao(database *sql.DB, s3 s3.DaoInterface) *Dao {
    objs := &Dao{database: database, s3: s3}
    return objs
}

func (d *Dao) DeleteArticleDao(id string) {
    d.s3.DeleteS3Image(imageName)
}

s3.go

package s3

//import

type S3 struct {
    APPID  string
    SECRET string
}

type DaoInterface interface {
    DeleteS3Image(imageName util.ImageName) error
}

func NewS3(appid, secret string) *S3 {
    objs := &S3{APPID: appid, SECRET: secret}
    return objs
}


func (objs *S3) DeleteS3Image(imageName util.ImageName) error {
    // method
}

The full source code is here(fix-test-dao):
https://github.com/jpskgc/article/tree/fix-test-dao

I expect there is not compile error in dao_test.go at SetupTest().
But the actual is not.
I want to resolve error and make test success.

Here is the error message.

type MockDaoInterface struct{Mock}

cannot use MockDaoInterface literal (type MockDaoInterface) as type s3.DaoInterface in assignment:

MockDaoInterface does not implement s3.DaoInterface (DeleteS3Image method has pointer receiver)
jpskgc.v5
  • 249
  • 1
  • 5
  • 9
  • You've implemented the delete method on a pointer receiver type (`func (_m *MockDaoInterface) DeleteS3Image`), so you need to pass in a pointer `s.dao.s3 = &MockDaoInterface{}`. – mkopriva Sep 08 '19 at 09:45
  • ... also if you read the error message, the issue should become clear. *"MockDaoInterface does not implement s3.DaoInterface (**DeleteS3Image method has pointer receiver**)"* – mkopriva Sep 08 '19 at 09:49
  • I changed to `s.dao.s3 = &MockDaoInterface{}`, and then another compile error occurs. `cannot use &MockDaoInterface literal (type *MockDaoInterface) as type s3.DaoInterface in assignment: *MockDaoInterface does not implement s3.DaoInterface (missing PostImageToS3 method)` – jpskgc.v5 Sep 08 '19 at 11:15
  • again the message is clear, you need to implement all of the methods of that interface. You original example has only DeleteS3Image method declared in the interface, so that's all you need to implement in that case. However if your actual interface has more methods, then you need to implement them all to be able to use the Mock and the also the `*s3.S3` needs to implement all of them, not just Delete. – mkopriva Sep 08 '19 at 11:18
  • ... note also that in Go, interfaces are satisfied *implicitly*. For a type `T` to satisfy the interface `I`, type `T` *MUST* implement all of the methods declared by the interface `I`. – mkopriva Sep 08 '19 at 11:22
  • Thanks for comment. Issue is resolved. – jpskgc.v5 Sep 08 '19 at 11:40

0 Answers0