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

Adding tests for validation and login #15

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

Adding tests for validation and login #15

wants to merge 4 commits into from

Conversation

jessicamosouza
Copy link
Owner

No description provided.

@jessicamosouza jessicamosouza added the enhancement New feature or request label Nov 28, 2023
@jessicamosouza jessicamosouza self-assigned this Nov 28, 2023
Copy link
Collaborator

@brunomvsouza brunomvsouza left a comment

Choose a reason for hiding this comment

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

Conferi rapidinho, qquer dúvida me fala. É esperado que tenha dúvidas ;)

http/login_test.go Outdated Show resolved Hide resolved
http/login_test.go Outdated Show resolved Hide resolved
http/login_test.go Outdated Show resolved Hide resolved
http/login_test.go Show resolved Hide resolved
uservalidation/user.go Outdated Show resolved Hide resolved
uservalidation/user_test.go Outdated Show resolved Hide resolved
uservalidation/user_test.go Outdated Show resolved Hide resolved
t.Parallel()

t.Run("Successful body read", func(t *testing.T) {
t.Parallel()
Copy link
Collaborator

Choose a reason for hiding this comment

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

C entendeu direitinho pra que o t.Parallel serve e como ele funciona?


t.Run("Handle error reading request body", func(t *testing.T) {
t.Parallel()
req, err := http.NewRequest(http.MethodGet, "/", &ErrorReader{})
Copy link
Collaborator

Choose a reason for hiding this comment

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

Como ErrorReader é usado só dentro deste mesmo pacote, não precisa exportar ele. :)

func testLoginErrors(t *testing.T) {
t.Parallel()

methodsToTest := []string{http.MethodDelete, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodOptions}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Acho que assim ficaria mais fácil de entender. Pense no código como uma leitura, quanto mais claros os nomes das variáveis forem, menos contexto precisa ser carregado na cabeça pra entender o código.

Suggested change
methodsToTest := []string{http.MethodDelete, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodOptions}
forbiddenMethods := []string{http.MethodDelete, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodOptions}

})
}

func assertResponseStatus(t *testing.T, req *http.Request, status int) string {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Quando vc define alguma coisa em um arquivo de teste, essa parada fica disponível pra todos os testes que usem o mesmo pacote. Como essa função faz assertion do status HTTP da resposta de LoginUserHandler especificamente, vale um ou outro dos abaixo:

Um: Deixar claro no nome que a assertion é para LoginUserHandler.

Outro: Aceitar como parâmetro a função. Ficaria algo assim:

func assertResponseStatus(t *testing.T, fn http.HandleFunc, req *http.Request, status int) string {
  t.Helper()

	rec := httptest.NewRecorder()
	fn(rec, req)
	require.Equal(t, status, rec.Code)
	return rec.Body.String()
}

// Usado assim, por exemplo:
assertResponseStatus(t, LoginUserHandler, req, http.StatusOK)

Se você optar por outro, vale criar um arquivo shared_test.go pra centralizar esses helpers de teste.

Outra dica legal é usar t.Helper() em helper functions de teste. Isso faz com que, caso o teste falhe aqui (no require.Equal, por exemplo), o report de teste do Go vai mostrar que deu erro em quem chamou a função que usa t.Helper() ao invés de dentro da função que usa t.Helper().


func CheckName(name string) error {
if name == "" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Tende a ser uma boa ideia sanitizar inputs string por espaços antes e depois do texto. É relativamente fácil em interfaces esquecer um espaço antes ou depois do valor de um campo e não perceber. strings.TrimSpace() tende a ser suficiente.

Suggested change
if name == "" {
sanitizedName := strings.TrimSpace(name)
if sanitizedName == "" {

false,
},
User{"", "", "john@doe.com", "Password123!"},
false,
false,
},
}
for _, tt := range tests {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Normalmente variáveis com duas letras repetidas inferem coleções em Go. Como tá sendo usada pra inferir um único teste aqui pode gerar confusão.

Uma forma de resolver seria a abaixo, levando em consideração que em testes a variável t já é usada.

Suggested change
for _, tt := range tests {
for _, tc := range testCases {

false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := Validate(tt.args.user, tt.args.isSignUp); (err != nil) != tt.wantErr {
t.Errorf("Validate() error = %v, expectedError %v", err, tt.wantErr)
if err := Validate(tt.inputUser, tt.inputIsSignUp); (err != nil) != tt.outputErr {
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. Se o valor do erro for significativo pra quem usa Validate, vale a pena conferí-lo aqui além de checar se veio erro ou não.
  2. Vale usar require.NoError (se for manter como está), e require.ErrorIs se o valor do erro for significativo pra quem usa Validate.

executeTestCases(t, testCases)
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
resp := tt.testFunc(tt.input)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Como testFunc não varia, dá pra chamar CheckEmail direto aqui e economizar umas linhas de código.

Suggested change
resp := tt.testFunc(tt.input)
resp := CheckEmail(tt.input)

input T
expectedError error
testFunc func(T) error
}) {
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
resp := tt.testFunc(tt.input)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
resp := tt.testFunc(tt.input)
resp := checkPassword(tt.input)

@brunomvsouza brunomvsouza requested review from brunomvsouza and removed request for brunomvsouza July 17, 2024 01:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

Successfully merging this pull request may close these issues.

2 participants