Recently I started writing unit tests on go.I received a task to conduct tests on all layers.I did it successfully on the repository and service layer, but there were problems on the handlers.I corny just don't understand how to write it here.
func (h *Handler) createAddress(c *gin.Context) error {
var (
data *schema.AddressRequest
err error
)
if err = c.BindJSON(&data); err != nil {
return err
}
if err = data.ValidateAddress(); err != nil {
return err
}
res, err := h.services.Address.Create(c.Request.Context(), data, c.ClientIP())
if err != nil {
return err
}
return schema.Respond(res, c)
}
here is a certain function that I am testing
func TestCreateAddress(t *testing.T) {
t.Run("Success", func(t *testing.T) {
addressData := &schema.AddressRequest{
Country: "Kazakhstan",
City: "Almaty",
District: "Medeu",
PostIndex: "050000",
Street: "Abay",
Building: "123",
Floor: "4",
Office: "42",
}
mockAddressService := new(serviceMocks.Address)
mockAddressService.On("Create", mock.Anything, addressData, mock.AnythingOfType("string")).Return(&model.Address{}, nil)
mockContext, _ := gin.CreateTestContext(httptest.NewRecorder())
mockContext.Request, _ = http.NewRequest(http.MethodPost, "/api/v1/address", nil)
mockContext.Set("ClientIP", "127.0.0.1")
handler := &Handler{
services: &service.Services{
Address: mockAddressService,
},
}
err := handler.createAddress(mockContext)
assert.NoError(t, err)
mockAddressService.AssertExpectations(t)
})
t.Run("Bad", func(t *testing.T) {
addressData := &schema.AddressRequest{
Country: "",
City: "",
District: "",
PostIndex: "",
Street: "",
Building: "",
Floor: "",
Office: "",
}
mockAddressService := new(serviceMocks.Address)
mockContext, _ := gin.CreateTestContext(httptest.NewRecorder())
mockContext.Request, _ = http.NewRequest(http.MethodPost, "/api/v1/address", nil)
mockContext.Set("ClientIP", "127.0.0.1")
handler := &Handler{
services: &service.Services{
Address: mockAddressService,
},
}
err := handler.createAddress(addressData)
assert.Error(t, err)
mockAddressService.AssertExpectations(t)
})
}
here is the test, and it comes out with the error below
User
=== RUN TestCreateAddress
=== RUN TestCreateAddress/Success
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
address_test.go:43:
Error Trace: C:/Users/r.ilebaev/GolandProjects/agent/internal/delivery/http/v1/address_test.go:43
Error: Received unexpected error:
invalid request
Test: TestCreateAddress/Success
address_test.go:45: FAIL: Create(string,*schema.AddressRequest,mock.AnythingOfTypeArgument)
at: [C:/Users/r.ilebaev/GolandProjects/agent/internal/delivery/http/v1/address_test.go:30]
address_test.go:45: FAIL: 0 out of 1 expectation(s) were met.
The code you are testing needs to make 1 more call(s).
at: [C:/Users/r.ilebaev/GolandProjects/agent/internal/delivery/http/v1/address_test.go:45]
--- FAIL: TestCreateAddress (0.00s)
--- FAIL: TestCreateAddress/Success (0.00s)
FAIL
Process finished with the exit code 1
I'm not asking for any help on how to fix the code, but judging by the way I write and what functions I'm testing, I'd like to understand some general principle for testing get,post, put and delete requests and functions at the handel level that use the gin and gorm package
at the end I will throw off the very function to which the handler is referred
func (s *AddressService) Create(
ctx context.Context,
address *schema.AddressRequest,
clientIP string,
) (*model.Address, error) {
if address == nil {
return nil, werr.ErrParseErrorBody
}
res, err := s.repos.Address.Create(ctx, address.ToModel())
if err != nil {
return nil, err
}
return res, err
}
....................................................................................................................