I'm setting unit test for api(golang).
It seems to use mocking. But I don't understand how to code to success.
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 it fails because dao.go calls method from s3.dao.
dao_test.go
package dao
// import
type DaoSuite struct {
    suite.Suite
    db   *sql.DB
    mock sqlmock.Sqlmock
    dao  *Dao
    s3   *s3.S3
}
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)
}
func (s *DaoSuite) TestDeleteArticleDao() {
    // some method
    // here test fails because DeleteArticleDao calls method from another package.
    s.dao.DeleteArticleDao("1")
}
func (s *DaoSuite) TearDownTest() {
    s.db.Close()
    s.Assert().NoError(s.mock.ExpectationsWereMet())
}
dao.go
package dao
// import
type Dao struct {
    database *sql.DB
    s3       *s3.S3
}
func NewDao(database *sql.DB, s3 *s3.S3) *Dao {
    objs := &Dao{database: database, s3: s3}
    return objs
}
func (d *Dao) DeleteArticleDao(id string) {
    //generate imageName
    //here calls method in package s3
    //here test fails 
    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 the test success in dao_test.go.
But the actual is it fails because dao.go calls method from s3 package.
I want to know how to mock DeleteS3Image in package s3 to avoid error and success test.
Here is the error when running go test -v at dao_test.go.
$ go test -v
--- FAIL: TestDaoSuite (0.00s)
    --- FAIL: TestDaoSuite/TestDeleteArticleDao (0.00s)
        dao_test.go:221: 
                Error Trace:    dao_test.go:221
                                                        suite.go:122
                                                        panic.go:522
                                                        panic.go:82
                                                        signal_unix.go:390
                                                        s3.go:66
                                                        dao.go:74
                                                        dao_test.go:156
                Error:          Received unexpected error:
                                there is a remaining expectation which was not matched: ExpectedBegin => expecting database transaction Begin
                Test:           TestDaoSuite/TestDeleteArticleDao
        suite.go:61: test panicked: runtime error: invalid memory address or nil pointer dereference
 
    