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

Mutate the state of arguments sent to mocked functions #861

Open
dnlopes opened this issue Dec 19, 2024 · 2 comments
Open

Mutate the state of arguments sent to mocked functions #861

dnlopes opened this issue Dec 19, 2024 · 2 comments

Comments

@dnlopes
Copy link

dnlopes commented Dec 19, 2024

Description

I was wondering if it's possible to define functions to be able to manipulate the state of objects that are sent as inputs to the Mock object.

See the example function below:

func (r SampleStruct) SampleMethod() {
  myKubernetesObject := r.setup()
  r.kubeClient.Observe(&myKubernetesObject)
  
  if myKubernetesObject.Identifier != "" {
    // do something
  }
}

In this example, I'm writing an unit test for the SampleMethod function. I will have a mocked struct that replaces the real kubeClient. The thing is: the real client will populate the myKubernetesObject struct, and subsequent logic depends on the content of that object to be filled (as you can see on the subsequent if condition).

Has Mockery any out of the box solution for this? For example, being able to define hooks that would be called by the Mocking framework, and could be used to manipulate the input objects received by the mocked methods? Something like:

mockedKubeClient.On("Observe", mock.Anything).SideEffect(func (kubeObject *metav1.Object) {
  kubeObject.Identifier = "dummy"
}

Here, the Mocking framework would invoke my side_effect function declared inline, to mutate the input object, so the SampleMethod can be tested properly.

Maybe I missed something from reading the docs, or maybe this is not supported at all?

Thanks in advance!

@LandonTClipp
Copy link
Collaborator

LandonTClipp commented Dec 26, 2024

You might want to look into the RunAndReturn method of mockery mocks (as part of the .EXPECT() structs: https://vektra.github.io/mockery/v2.50/features/#expecter-structs

This particular method allows you to define a function that will take as input the arguments of your function, perform some action, and have your mock return the same values as what your RunAndReturn function returns.

Alternatively, you could use testify's Run method directly but this isn't as type safe, so RunAndReturn is the best way to do this.

I admit that the docs are not super clear about this, that's something for me to fix.

@dnlopes
Copy link
Author

dnlopes commented Dec 30, 2024

Ah great! That seems to fit my use case exactly. Will test it out, thanks.

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

No branches or pull requests

2 participants