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

Define Interactor keyword arguments explicitly to improve testability #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

dostu
Copy link
Contributor

@dostu dostu commented Jun 12, 2023

Similar to #20

We could define keyword params methods similarly to plain params. This would improve the testability of those methods too.

Currently interactor methods accept a hash so this would be a breaking change. But there are not that many places where we explicitly pass in a hash in core. Here are the required changes: https://github.com/vinted/core/pull/75828

@vinted/platform-backend @oleg-vinted

@dostu dostu force-pushed the feature/keyword_params_strict_args branch 2 times, most recently from 49d9270 to 1846ba1 Compare June 12, 2023 12:03
@dostu dostu changed the title Define keyword arguments explicitly Define Interactor keyword arguments explicitly to improve testability Jun 12, 2023
@dostu dostu marked this pull request as ready for review June 12, 2023 12:37
@dostu dostu force-pushed the feature/keyword_params_strict_args branch from 1846ba1 to ee98de2 Compare June 15, 2023 10:57
Copy link
Contributor

@andriusm andriusm left a comment

Choose a reason for hiding this comment

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

From the changes in this PR it's not clear how this is supposed to help with testability.

@@ -26,34 +26,38 @@ def self.attr_readers(target_class, attributes)

def self.methods_with_params(attributes = [])
signature = attributes.join(', ')
initializer_params = signature
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this line needed?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not strictly necessary, I would assume this is to keep symmetry with .methods_with_keywords which also has both of these variables.

@andriusm andriusm closed this May 3, 2024
@oleg-vinted oleg-vinted reopened this Sep 4, 2024
@oleg-vinted
Copy link
Contributor

I'd like to revive this initiative as we've yet again had a problem with stubbing interactors incorrectly, and this change would have prevented the issue in the first place. If there's enough interest, I volunteer to drive this to completion.

@oleg-vinted
Copy link
Contributor

From the changes in this PR it's not clear how this is supposed to help with testability.

@andriusm If we define the parameters of .for, .with, and .run explicitly, then mocking libraries can detect if you're mocking the method correctly, i.e. the mock/stub has a compatible signature, and raise an exception.

@andriusm
Copy link
Contributor

andriusm commented Sep 5, 2024

@oleg-vinted I mean, you can do that if you really want, but I wonder whether this is the correct direction in the first place. Mocking interactor classes always seemed shady to me. It's the core of business logic, why would this be mocked. If one interactor class is calling other interactors and some of them are mocked in tests then I don't think the test is serving its purpose of protecting from changes to interactors that are a level below. Our interactors don't usually return a value or throw errors (except for extreme cases), they usually fail silently, so I think mocking them provides a false sense of security because all we assert is that something is invoked and we don't alter the execution path. My perspective is that an interactor should not invoke other interactors and if there's generic common code that needs to be executed for multiple interactors, it should be a helper function. I know it's not the case right now, but I'm not in favor of lessening the pain and making it easier to make poor choices.

@oleg-vinted
Copy link
Contributor

Strictly speaking, interactors calling each other transitively wasn't the cause of the problem I mentioned in the comment above, it was a job calling an interactor that performs the necessary operation. Interactor's parameters were changed, and job tests didn't fail because the invocation was stubbed, and the mocking library could not validate if the parameters were correct.

Even then, I'm not sure what alternative you're proposing here other than keeping things as is.

@andriusm
Copy link
Contributor

andriusm commented Sep 5, 2024

The alternative I would prefer is to enforce that interactors are not mocked in tests. But I see you're determined to push this one through.

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

Successfully merging this pull request may close these issues.

3 participants