I am experiencing the following error
assert: mock: I don't know what to return because the method call was unexpected.
Either do Mock.On("Send").Return(...) first, or remove the Send() call.
This method was unexpected:
Send(services.ConfirmAccountEmail,repository.User)
When consuming real API, it sends the email and mailer.Send is called
So I have an API, which creates Router and routes are registered in Router. Router accepts a parameter of interface mailer in its constructor and thats where I want to tweak which mailer would be used - real or the fake.
The code is as following. I know there's a lot of space for improvement, but now I'm primarily interested in mocking
Mailer interface:
type Mailer interface {
Send(email Email, receiver User) error
}
Email is also an interface.
The struct that implements Mailer interface:
type EmailDelivery struct {
Config Config
}
func (service EmailDelivery) Send(email Email, receiver User) error {
//Code
}
Router code:
type Router struct {
api Api
db *gorm.DB
redisClient *redis.Client
config Config
mailer Mailer
}
func NewRouter(api Api, db *gorm.DB, redisClient *redis.Client, config Config, mailer Mailer) Router {
return Router{api, db, redisClient, config, mailer}
}
func (router *Router) AddRoutes() {
router.api.AddRouteWithCors("/register", "POST", WithRequestLog(router.RegisterHandler))
//...
}
func (router *Router) RegisterHandler(w http.ResponseWriter, r *http.Request) {
//...
email := NewConfirmAccountEmail(router.config, "Email subject", "email_template")
router.mailer.Send(email, user)
}
Api code:
func (api *Api) InitializeRoutes(mailer Mailer) *Router {
//...
router := NewRouter(*api, api.db, api.redisClient, config, mailer)
router.AddRoutes()
//...
}
Test:
type MockMailer struct {
mock.Mock
}
func (m *MockMailer) Send(email Email, receiver User) error {
args := m.Called(email, receiver)
return args.Error(0)
}
In test:
mailer := new(MockMailer)
mailer.On("Send", mock.Anything, mock.Anything).Return(nil)
//Execute the code that is calling send method - calling endpoint
api := NewApi(config.ServerPort, db, nil)
mailer := new(MockMailer)
router := api.InitializeRoutes(mailer)
req, err := http.NewRequest(http.MethodPost, "/register", bytes.NewReader(body))
w := httptest.NewRecorder()
router.RegisterHandler(w, req)
res := w.Result()
defer res.Body.Close()
mailer.AssertExpectations(t)
//..other expectations
Debugging shows that it entered send method, but I still have this error
Could it be that interface is creating an issue? Or maybe mock.Anything?
Thanks
The method implemented seems to not be the same as the one in the interface; the parameter types differ:
Send(email Email, receiver User) error!=Send(services.ConfirmAccountEmail,repository.User).You may want to check if the implemented structure in the tested structure implements your interface with the correct parameter types.
We lack of information to help you resolve this.