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

.On().Return() doesn't enforce expectation for the returned value #1574

Open
andrehoong-pixieset opened this issue Mar 9, 2024 · 1 comment
Labels

Comments

@andrehoong-pixieset
Copy link

andrehoong-pixieset commented Mar 9, 2024

Hey guys I have this test:

func TestDownloadFromS3Error1(t *testing.T) {
	mockS3Interface := &MockS3Interface{
		Error: errors.New("something went wrong on download"),
	}
	mockS3Interface.On("GetObject", &s3.GetObjectInput{
		Bucket: aws.String(testBucket),
		Key:    aws.String(testKey),
	}).Return(nil, "aaaaa").Once()

	client := awsclient.AWSClient{
		S3Interface: mockS3Interface,
	}

	downloadFile, _ := os.CreateTemp(os.TempDir(), "testDownloadFromS3-*.txt")
	defer downloadFile.Close()
	defer os.Remove(downloadFile.Name())

	client.DownloadFromS3(testBucket, testKey, downloadFile)

	mockS3Interface.AssertExpectations(t)
	downloadFileInfo, _ := downloadFile.Stat()
 	if downloadFileInfo.Size() != 0 {
		t.Fatalf("The downloaded file should be empty on S3 failure")
	}

	expectedLog := fmt.Sprintf("Error downloading from S3:\n%s", mockS3Interface.Error.Error())
	assertLogsContain(expectedLog, t)
}

Which is implementing this mocked function:

// GetObject is a mock implementation of the GetObject method
func (m *MockS3Interface) GetObject(input *s3.GetObjectInput) (*s3.GetObjectOutput, error) {
	m.Called(input)

	if m.Error != nil {
		return nil, m.Error
	}

	return &s3.GetObjectOutput{
		Body: io.NopCloser(bytes.NewReader([]byte(m.Body))),
	}, nil
}

I notice that the expected return value is not actually being enforced. IE: my MockS3Interface is given the error "something went wrong on download", but the expected error to be returned is "aaaaa" (defined after the .On call). Even though the expected return "aaaa" differs from what is actually returned the test still passes

I know I can do something like args := m.Called(input) to get the values defined in .Return() but shouldn't the expected return values also be enforced similar to how the arguments passed into On()are.

I'm still a noob when it comes to Golang and mocking so this might just be a misunderstanding on my end, but any insight is greatly appreciated. Thanks in advance!

@brackendawson
Copy link
Collaborator

brackendawson commented Mar 10, 2024

Your mock is wrong, it should look like this:

func (m *MockS3Interface) GetObject(input *s3.GetObjectInput) (*s3.GetObjectOutput, error) {
	args := m.Called(input)
	return args.Get(0).(*s3.GetObjectOutput), args.Error(1)
}

And MockS3Interface should have no fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants