-
Notifications
You must be signed in to change notification settings - Fork 24
test: mock context in TableTestCommand #20
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
Conversation
mwbrooks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I hope the 200 lines don't scare you off. It should be easy scrolling and I've left a few comments to guide you through the repetition to the important parts!
| ExpectedAsserts func(*testing.T, *shared.ClientsMock) // Optional | ||
| ExpectedError error // Optional | ||
| ExpectedErrorStrings []string // Optional | ||
| Setup func(*testing.T, context.Context, *shared.ClientsMock, *shared.ClientFactory) // Optional |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: 💠 This is the main change of the pull request and the arguments below are only showing as changed because the comment indentation was adjusted by the formatter.
| for name, tt := range commandTests { | ||
| t.Run(name, func(t *testing.T) { | ||
| // Create mocks | ||
| ctxMock := slackcontext.MockContext(t.Context()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: Here we mock the context with the standard values that a new CLI process will initialize.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 It's so neat that this can be used for both setup and execution. One context for all!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, it's nice. I wonder how we can document that values set in MockContext are the values "guaranteed" to exist when a Cobra command executes (cmd.ExecuteContext(ctx))? Perhaps we can document this in the header of slackcontext.go? For example, Golang's context.go has a large comment block above the package context to explain the usage of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow I'm fascinated with the godoc standards of this upstream. I know go claims to not have ideal standards here, but we should feel generous with this documentation! 📚 ✨
| // Setup custom mocks (higher priority than default mocks) | ||
| if tt.Setup != nil { | ||
| tt.Setup(t, clientsMock, clients) | ||
| tt.Setup(t, ctxMock, clientsMock, clients) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: Here we pass the mocked context into .Setup and in the future we could return the ctx in case it's been modified by .Setup
| // Execute the command | ||
| cmd.SetArgs(tt.CmdArgs) | ||
| err := cmd.Execute() | ||
| err := cmd.ExecuteContext(ctxMock) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: ⚡ We now execute the command with the context, so that cmd.Context() will return this context. This matches how root.go executes the CLI with cmd.ExecuteContext(ctx).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small change to arguments and one giant change for testing commands 🚀 ✨
| "errors if not run in a project directory": { | ||
| ExpectedError: slackerror.New(slackerror.ErrInvalidAppDirectory), | ||
| Setup: func(t *testing.T, cm *shared.ClientsMock, cf *shared.ClientFactory) { | ||
| Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: This change is made about 200 times 😆 Scroll down to the very bottom to see the updates to testutil.TableTestCommand that implement this feature. ⬇️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Praises @mwbrooks! This is a tedious but meaningful change 🎁
zimeg
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧪 What a wonderful and focused PR this is for testing improvements.
I'm excited for this as more commands begin to follow this table testing pattern and the code being tested uses a single context. These are all great changes being made 🚢 💨
| "errors if not run in a project directory": { | ||
| ExpectedError: slackerror.New(slackerror.ErrInvalidAppDirectory), | ||
| Setup: func(t *testing.T, cm *shared.ClientsMock, cf *shared.ClientFactory) { | ||
| Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Praises @mwbrooks! This is a tedious but meaningful change 🎁
| // Execute the command | ||
| cmd.SetArgs(tt.CmdArgs) | ||
| err := cmd.Execute() | ||
| err := cmd.ExecuteContext(ctxMock) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One small change to arguments and one giant change for testing commands 🚀 ✨
| for name, tt := range commandTests { | ||
| t.Run(name, func(t *testing.T) { | ||
| // Create mocks | ||
| ctxMock := slackcontext.MockContext(t.Context()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 It's so neat that this can be used for both setup and execution. One context for all!
|
Thanks for taking the time to review this PR @zimeg! 🙇🏻 I agree, it'll be nice to get our tests to be more consistent. I didn't expect this work to move that forward, but it is! 🧪 |
Summary
Depends on PR #7 and ready for review when PR #7 is merged.
This pull request updates
testutil.TableTestCommandto use a mocked context and executes the command with the provided context.Currently, the
testutil.TableTestCommanddoesn't define a context. This has 2 drawbacks:context.Background()and must manually mock the context to include required value that are initialized when a CLI command is run (e.g.SessionID)..Setup(...)- are not available to the Cobra command or anycmd.Context()calls.By having
testutil.TableTestCommandmock the context, pass it to.Setup, and then execute the command with the same context, we match how the CLI initializes and executes a command inmain.goandcmd/root.go.A small improvement may be for the
.Setupto return actx. However, this is only important when the context is modified and we don't do that right now.Requirements