stretchr / testify

A toolkit with common assertions and mocks that plays nicely with the standard library
MIT License
22.52k stars 1.56k forks source link

feat(mock): add Replace method to Call #1511

Open lefinal opened 7 months ago

lefinal commented 7 months ago

Summary

The Replace function allows for existing mock handlers to be replaced with new mock handlers, essentially allowing for the same method to be called with different return values. This increases flexibility and functionality in testing scenarios.

Changes

Added Replace() method to *mock.Call as well as a few tests.

Motivation

A possible use-case of mock is specifying all normally expected calls in a test setup. These calls return default or "correct" values and use .Maybe(). If scenarios are tested, where a mocked object returns other values, one currently needs to unset the call and then create a new one with On. The newly added Replace() method is syntactic sugar for this use-case by calling Unset() first, and then On with the call's method and arguments.

This added test is also an example:

func Test_Mock_Replace(t *testing.T) {
    var mockedService = &TestExampleImplementation{}

    mockedService.On("TheExampleMethod", 1, 2, 3).Return(1, nil)
    mockedService.On("TheExampleMethod", 1, 2, 3).Replace().Return(2, nil)

    res, _ := mockedService.TheExampleMethod(1, 2, 3)
    assert.Equal(t, 2, res, "should return correct value")
}

The first call to On might be located in a test setup for the "good route". The second one in a test for some specific functionality that relies on the service returning different values or errors.

Related issues

none

lefinal commented 6 months ago

Any updates on this?

st3penta commented 4 months ago

This is already possible using the Unset method, as shown in this example.

I just tried it in this sample test and it worked, this is the output:

=== RUN   TestExample
    prog_test.go:30: PASS:  DoSomething(int,int,int)
    prog_test.go:43: PASS:  DoSomething(int,int,int)
--- PASS: TestExample (0.00s)
PASS