Skip to content

Instantly share code, notes, and snippets.

@rgarcia
Last active August 29, 2015 14:10
Show Gist options
  • Save rgarcia/5bff218b34b6c1a60a44 to your computer and use it in GitHub Desktop.
Save rgarcia/5bff218b34b6c1a60a44 to your computer and use it in GitHub Desktop.
testing read-only interfaces
package foo
type Foo struct {
}
type DB interface {
Find(string) (Foo, error)
}
package foo
import "testing"
type injectableDB interface {
DB
Insert(string, Foo) error
}
func testDBFind(t *testing.T, db injectableDB) {
// Find("asdf") -> returns nothing
// Insert("asdf", Foo{}) -> successfully inserts
// Find("asdf") -> returns same Foo inserted above
}
package foo
import "errors"
type MemoryDB struct {
foos map[string]Foo
}
func NewMemoryDB() DB {
return &MemoryDB{
foos: make(map[string]Foo),
}
}
func (mdb *MemoryDB) Find(id string) (Foo, error) {
if foo, ok := mdb.foos[id]; ok {
return foo, nil
}
return Foo{}, errors.New("unknown foo")
}
package foo
import "testing"
type injectableMemoryDB struct {
*MemoryDB
}
func (imdb *injectableMemoryDB) Insert(id string, foo Foo) error {
// insert into imdb.MemoryDB.foos
return nil
}
func TestMemoryDB(t *testing.T) {
db := NewMemoryDB()
mdb := db.(*MemoryDB)
testDBFind(t, &injectableMemoryDB{mdb})
}
package foo
type MongoDB struct {
// ...
}
func NewMongoDB() DB {
return &MongoDB{}
}
func (mdb *MongoDB) Find(id string) (Foo, error) {
// ...
return Foo{}, nil
}
package foo
import "testing"
type injectableMongoDB struct {
*MongoDB
}
func (imdb *injectableMongoDB) Insert(id string, foo Foo) error {
// insert using imdb.MongoDB internals
return nil
}
func TestMongoDB(t *testing.T) {
db := NewMongoDB()
mdb := db.(*MongoDB)
testDBFind(t, &injectableMongoDB{mdb})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment