Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create mocks helper #420

Closed
wants to merge 7 commits into from
Closed

Conversation

ncostamagna
Copy link

@ncostamagna ncostamagna commented Oct 28, 2020

Fixes

create mocks helper features

used for integration test in the applications without need to send any mails

package main

import (
	"github.com/sendgrid/sendgrid-go/helpers/mock"
)

func main() {

	// Send Mail
	sendMail()

	// start mocks server
	mock.StartTestServer()

	// add mock value
	mock.Add(&mock.Mock{
		StatusCode: 400,
		Body:       `{ "errors":[{ "message":"Example error.", "field":"example field" }] }`,
	})
	sendMail() // Response with mock data

	// add mock value
	mock.Add(&mock.Mock{
		StatusCode: 200,
	})
	sendMail() // Response with mock data

	// add mock value
	mock.Add(&mock.Mock{
		Err: errors.New("Has been an mock error"),
	})

	// stop mocks server
	mock.StopTestServer()

	sendMail() // Send Mail

	// start mocks server
	mock.StartTestServer()

	sendMail() // Response with mock data

	// clear mock
	mock.Flush()
	sendMail() // Send Mail

	// stop mocks server
	mock.StopTestServer()

}

func sendMail() {
	// send Sendgrid mail
}

with a complete coverage

func TestMain(m *testing.M) {
	mock.StartTestServer()
	run := m.Run()
	mock.StopTestServer()
	os.Exit(run)
}

func TestEmailSuccess(t *testing.T) {

	mock.Add(&mock.Mock{
		StatusCode: 202,
	})

	// Test email send success
	err := myService() 
}

func TestEmailStatusError(t *testing.T) {

	mock.Add(&mock.Mock{
		StatusCode: 400,
		Body:       `{ "errors":[{ "message":"Example error.", "field":"example field" }] }`,
	})

	// Test status code error
	err := myService() 
}

func TestEmailSengridError(t *testing.T) {

	mock.Add(&mock.Mock{
		Err:        errors.New("Has been an mock error"),
	})

	// Test sendgrid error
	err := myService() 
}


func myService() error {

	// ...

	response, err := sendgrid.API(request)

	if err != nil {
		// ...
		// sendgrid error
		return err
	}
	
	if response.StatusCode > 299 {
		// ...
		// status code error
		return fmt.Errorf("code: %d, body: %s", response.StatusCode, response.Body)
	}

	// ...
	// success
	return nil

}

example in

/examples/mocks/mocks.go

Checklist

  • I acknowledge that all my contributions will be made under the project's license
  • I have made a material change to the repo (functionality, testing, spelling, grammar)
  • I have read the Contribution Guidelines and my PR follows them
  • I have titled the PR appropriately
  • I have updated my branch with the main branch
  • I have added tests that prove my fix is effective or that my feature works
  • I have added the necessary documentation about the functionality in the appropriate .md file
  • I have added inline documentation to the code I modified

If you have questions, please file a support ticket, or create a GitHub Issue in this repository.

@thinkingserious thinkingserious added the status: code review request requesting a community code review or review from Twilio label Oct 28, 2020
@amclay
Copy link

amclay commented Oct 29, 2020

I love the idea, but I think it'd be more flexible to create an interface, and allow others to mock it in their own apps.

@classic-massok
Copy link

Ditto on @amclay. The idea of a built in mock is great for getting unit tests, but if this could also include interfacing out the Client I think it would provide even further flexibility for mocking. We're actually in this boat right now at our company.

@@ -8,6 +8,7 @@ import (

"github.com/sendgrid/rest"
"github.com/sendgrid/sendgrid-go/helpers/mail"
"github.com/sendgrid/sendgrid-go/helpers/mock"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like adding this dependency in non-dev environments.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @thinkingserious, how are you?
Yes, I think the same but is only place where we could intercept the request
I haven't found other place where we could intercept the request with the Mocks.

Where we could intercept the request with the mocks?

Thank you very much and greetings!

Nahuel

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good, thanks for asking. I trust the same is true with you!

I think we should first create the interface per issue #421.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @thinkingserious

I created a SendGrid interface for test integration,
this example is in examples/mocks

package main

import (
	"fmt"
	"os"

	"github.com/sendgrid/sendgrid-go"
	"github.com/sendgrid/sendgrid-go/helpers/mail"
	"github.com/sendgrid/sendgrid-go/helpers/mock"
)

func main() {

	// start mocks server
	mock.StartTestServer()

	// add mock value
	mock.Add(&mock.Mock{
		StatusCode: 400,
		Body:       `{ "errors":[{ "message":"Example error.", "field":"example field" }] }`,
	})


	simpleSendMail() // Response with mock data

	// stop mocks server
	mock.StopTestServer()

}

func simpleSendMail() {
	from := mail.NewEmail("Example User", "[email protected]")
	subject := "Sending with Twilio SendGrid is Fun"
	to := mail.NewEmail("Example User", "[email protected]")
	plainTextContent := "and easy to do anywhere, even with Go"
	htmlContent := "<strong>and easy to do anywhere, even with Go</strong>"
	message := mail.NewSingleEmail(from, subject, to, plainTextContent, htmlContent)
	
	// create mock client
	client := sendgrid.NewSendClientMock(os.Getenv("SENDGRID_API_KEY"))

	response, err := client.Send(message)
	if err != nil {
		fmt.Println("Simple Sengird Error: ")
		fmt.Println(err)
		fmt.Println("________________________________")
		fmt.Println()
	} else {
		fmt.Println("Simple Sengird Response: ")
		fmt.Println(response.StatusCode)
		fmt.Println(response.Body)
		fmt.Println(response.Headers)
		fmt.Println("________________________________")
		fmt.Println()
	}
}

@@ -70,6 +71,10 @@ func API(request rest.Request) (*rest.Response, error) {

// MakeRequest attempts a Twilio SendGrid request synchronously.
func MakeRequest(request rest.Request) (*rest.Response, error) {
if mock.Get() != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mocking should happen within the test environment.

Copy link
Author

@ncostamagna ncostamagna Nov 17, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hello @thinkingserious
Greate, I think that would be better we use "startTest()" and "endTest()" for setting to begine and end test,
In this way, the developers doesn't depends to the name of environment variable for them project.

best regards

Nahuel

@thinkingserious
Copy link
Contributor

Hello @ncostamagna,

I also agree with the comments above and the related issue #421.

What are your thoughts?

With best regards,

Elmer

@thinkingserious thinkingserious added status: waiting for feedback waiting for feedback from the submitter type: community enhancement feature request not on Twilio's roadmap and removed status: code review request requesting a community code review or review from Twilio labels Nov 16, 2020
Copy link
Contributor

@thinkingserious thinkingserious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will need an example of how to get started here.

}

func sendMail() {
m := mail.NewV3Mail()
content := mail.NewContent("text/html", "<h1>Hello world</h1>This is an example")

from := mail.NewEmail("envalidMail", "invalidMail@mail.com")
from := mail.NewEmail("Nahuel", "ncostamagna@hotmail.com.ar")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert to the example name and email.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @thinkingserious,
the example of how to get started mocks is in line 19 for start and line 42 for end

	mock.StartTestServer() // start mock server
	
	mock.StopTestServer() // end mock server

Do I write documentation in a markdown file?

Thanks you!
Merry christmas and happy new year!

@JenniferMah
Copy link
Contributor

Closing until PR feedback and failing tests are addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting for feedback waiting for feedback from the submitter type: community enhancement feature request not on Twilio's roadmap
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants