gotestify

Testify failing assertion for mocks when passing the correct args


Golang beginner here. I am trying to write tests for my struct which eventually mocks out the stats interface. The relevant part of my code looks below as far as the tests go.

// Test code
type MockStats struct {
    mock.Mock
}

func (m *MockStats) Mean(input []float64) (mean float64, err error) {
    args := m.Called(input)
    return (args.Get(0)).(float64), args.Error(1)
}

func TestCalculateWhenErrorCalculatingMean(t *testing.T) {

    m := new(MockStats)

    data := []float64{0.0, 0.1}
    r := ResponseAggregate{ExecutionTimes: data}

    // Expectations
    m.On("Mean", []float64{0.0, 0.1}).Return(float64(0.1), errors.New("Oops!")).Once()
    m.AssertExpectations(t)

    // Function call

    err := r.Calculate(m)

    // Data assertion
    assert.NotNil(t, err)
    if assert.Error(t, err) {
        assert.Equal(t, errors.New("error calculating average. Oops!"), err)
    }

}

My calling code looks like

type ResponseAggregate struct {
    ExecutionTimes             []float64
    AverageTime                float64
}


func (response *ResponseAggregate) Calculate(stats Stats) error {

    average, err := stats.Mean(response.ExecutionTimes)
    if err != nil {
        return fmt.Errorf("error calculating average. %v", err)
    }

    return nil

When I run my tests, I get the error

            The code you are testing needs to make 1 more call(s).

Could you help me out with what I am missing here? Thanks. BTW, using Go 1.16.3


Solution

  • You're actually calling m.AssertExpectation(t) before the call r.Calculate(m) is made. Thus, you try to check for the mocked method call before the method was called.

    Just put the assertion after r.Calculate(m) and it should be fine.