gojuno / minimock

Powerful mock generation tool for Go programming language
MIT License
633 stars 38 forks source link

Allow for checking mocked calls by hand using a call history #35

Closed Kangaroux closed 5 years ago

Kangaroux commented 5 years ago
type Adder interface {
    Add(a int, b int) int
}

mock := NewAdderMock(mc)

mock.Add(1, 2)
mock.Add(3, 4)
mock.Add(5, 6)

// A 'Calls' attribute would contain an array of all the calls to Add()
assert.Equal(t, 3, len(mock.AddMock.Calls))

This example is somewhat useless since the arguments are known at runtime. But in cases where you may want to ignore certain arguments, or where the actual value of the arguments are not known, this would be extremely useful.

A practical example of this would be testing a function which accepts a struct argument. You may only be interested in running assertions on a couple fields. Or perhaps the struct has a randomly generated field like a SessionID, and you want to verify that it's not blank. This would also provide a solution for #30.

Additionally, there would need to be a way to disable expectation checking from mc.Finish() for a given mock. If you decide to use .Calls then that means you are handling the assertions yourself and not relying on the minimock methods. If you didn't disable the check, then you would receive an error saying that there was an unexpected call to the mock.

This could look something like this:

defer mc.Finish()
mock := NewAdderMock(mc)
mock.AddMock.Ignore()

// Continue...
hexdigest commented 5 years ago

Hi @Kangaroux

Thanks for the proposal.

Let me start from the end. First of all I don't like the "Ignore" semantics. I would change it to mock.AddMock.ExpectAnything().Return(something). Because "Ignore" doesn't tell you anything. What are we going to ignore here? In the case of ExpectAnything, mc.Finish() will check only the fact that the "Add" method has been called within the test but it won't make any assertions on its arguments.

Also I want to remind you that there's always the AdderMock.Set() option that solves all the problems you described above. Do you think having ".Calls" will result in less boiler plate code than passing a closure to Set() ?

Beside that I'm fine with adding a call history and in fact I have been thinking about it for quite a while. You can wait a couple of weeks or send your PR :)

Kangaroux commented 5 years ago

ExpectAnything works. The naming could be better. SkipExpectations, CaptureOnly, etc.

As for using Set, while that certainly works it ends up doing a bit of redundant work since minimock is already capturing arguments and creates a struct to store them in.

I'll see if I can get a PR put up over the long weekend

Kangaroux commented 5 years ago

PR for call args: https://github.com/gojuno/minimock/pull/36

Kangaroux commented 5 years ago

Closed and moved to #38