Closed pkieltyka closed 8 years ago
The most common approach is to have an interface and define its implementations (1) and then use dependency injection (2):
1:
// whatever.go
package whatever
type interface Interface {
Do() error
}
type Whatever struct {
}
func (w *Whatever) Do() error {
// implementation
}
var _ Interface = &Whatever{}
// whatever_test.go
package whatever_test
import "github.com/pressly/geoy/whatever"
type WhateverMock struct {
}
func (w *WhateverMock) Do() error {
// mock implementation
}
var _ whatever.Interface = &WhateverMock{}
2:
// main.go
import "github.com/pressly/geoy/whatever"
func main() {
w := &whatever.Whatever{}
app := NewApp(w)
// app uses real implementation
// ...
}
// whatever_test.go
func TestWhatever(t *testing.T) {
w := &MockWhatever{}
app := NewApp(w)
// test app uses mock implementation
// ...
}
My initial approach was recording all the input and output we got from the google maps API, since we can't just fake a server and get mock respondes (actual Google Maps endpoints are never exposed, nor cannot be changed).
The reason I am using build tags is that this mock takes place here in geoy, here is where responses are emulated and not in the file we want to test (which is outside geoy).
I am open to suggestions, I agree that it would be better to keep this as part of the files we want to test.
@xiam your approach makes sense, but I think it works outside of Go's conventional ways, and makes other things more difficult. Can you refactor the mocks based on Vojtech's suggestions? ie. we could export an interface from geoy
called like..
Finder
with the methods that we use to look up location/place data just like you've done. Then, we can implement a MapsClient based on Finder interface using Google Maps API .. and again, we can make a Mock client easily this way.
The mocking in this library feels very strange, brittle and error-prone. I don't have a ton of mocking experience, but the code here looks like its doing mocking via a mixin using build tags. Mocking is only useful for tests, so why dont we use
_test.go
for the test portion of the code? .. I think we need to heavily refactor how we are mocking in this library.cc: @VojtechVitek @c2h5oh