我正在尝试创建一个模拟Go Flex SDK for Google Cloud Datastore周围的测试的包装。虽然我目前成功运行从我的测试窗口,一个单独的终端使用嘲笑Go数据库SDK
gcloud beta emulators datastore start --no-store-on-disk
本地主机模拟器,我宁愿创建运行作为测试过程本身(的一部分模拟数据库模拟器不exec
荷兰国际集团以上),以便我可以并行运行多个测试,每个测试都有自己的数据库模拟器。
我遇到了Google SDK未实现我的界面的问题。
我的包装包含以下代码:
package google
import (
"context"
"cloud.google.com/go/datastore"
)
type (
// Datastore is a wrapper for the Google Cloud Datastore Client.
Datastore datastore.Client
// Datastorer represents things that can operate like a datastore.Client.
Datastorer interface {
Delete(context.Context, *datastore.Key) error
Get(context.Context, *datastore.Key, interface{}) error
GetAll(context.Context, *datastore.Query, interface{}) ([]*datastore.Key, error)
Put(context.Context, *datastore.Key, interface{}) (*datastore.Key, error)
PutMulti(context.Context, []*datastore.Key, interface{}) ([]*datastore.Key, error)
RunInTransaction(context.Context, func(Transactioner) error, ...datastore.TransactionOption) (*datastore.Commit, error)
}
// Transactioner represents things that can operate like a datastore.Transaction.
Transactioner interface {
Commit() (*datastore.Commit, error)
Delete(*datastore.Key) error
DeleteMulti([]*datastore.Key) error
Get(*datastore.Key, interface{}) error
GetMulti([]*datastore.Key, interface{}) error
Put(*datastore.Key, interface{}) (*datastore.PendingKey, error)
PutMulti([]*datastore.Key, interface{}) ([]*datastore.PendingKey, error)
Rollback() error
}
)
// Delete deletes the entity for the given key.
func (d *Datastore) Delete(ctx context.Context, key *datastore.Key) error {
return (*datastore.Client)(d).Delete(ctx, key)
}
// Get retrieves the entity for the given key.
func (d *Datastore) Get(ctx context.Context, key *datastore.Key, dst interface{}) error {
return (*datastore.Client)(d).Get(ctx, key, dst)
}
// GetAll retrieves all entities for the given query.
func (d *Datastore) GetAll(ctx context.Context, q *datastore.Query, dst interface{}) ([]*datastore.Key, error) {
return (*datastore.Client)(d).GetAll(ctx, q, dst)
}
// Put stores an entity for the given key.
func (d *Datastore) Put(ctx context.Context, key *datastore.Key, src interface{}) (*datastore.Key, error) {
return (*datastore.Client)(d).Put(ctx, key, src)
}
// PutMulti is a batch version of Put.
func (d *Datastore) PutMulti(ctx context.Context, keys []*datastore.Key, src interface{}) ([]*datastore.Key, error) {
return (*datastore.Client)(d).PutMulti(ctx, keys, src)
}
// RunInTransaction runs the given function in a transaction.
func (d *Datastore) RunInTransaction(ctx context.Context, f func(tx Transactioner) error, opts ...datastore.TransactionOption) (*datastore.Commit, error) {
return (*datastore.Client)(d).RunInTransaction(ctx, func(t *datastore.Transaction) error {
return f(t)
}, opts...)
}
注意,这些接口不效仿完整的SDK。我只包括我实际在代码中调用的函数。稍后我会根据需要添加新的。
当我尝试使用的*datastore.Client
实例作为Datastorer
,我得到以下错误:
cannot use client (type *"cloud.google.com/go/datastore".Client) as type Datastorer in field value:
*"cloud.google.com/go/datastore".Client does not implement Datastorer (wrong type for RunInTransaction method)
have RunInTransaction(context.Context, func(*"cloud.google.com/go/datastore".Transaction) error, ..."cloud.google.com/go/datastore".TransactionOption) (*"cloud.google.com/go/datastore".Commit, error)
want RunInTransaction(context.Context, func(Transactioner) error, ..."cloud.google.com/go/datastore".TransactionOption) (*"cloud.google.com/go/datastore".Commit, error)
因为*datastore.Client
需要一个函数,它接受一个func(*datastore.Transaction) error
和我的接口想要一个func(Transactioner) error
。
有什么办法可以改变它,以便它编译?
如果我能得到它的工作,我打算创建实现我的Datastorer
和Transactioner
接口的类型,并使用地图来模拟真实的数据库。至于tranactions去测试我可以使用sync.Mutex
如果我需要他们,但由于每个测试是一个单一的线程,并将获得自己的数据库对象,我可能不需要锁定它们。
解决此问题的一种方法是在接口和实现之间有一个中介,基本上是一个实现您想要使用的接口的薄包装,然后将正确的类型传递给基础具体类型。例如。;它需要一个'Transactioner',将它转换为'* datastore.Transaction',然后将它传递给'* datastore.Client'。 – mkopriva
这就是我正在意识到的。我已经取得了一些进展,但遇到了'datastore.Query'类型的新问题。如果我找到完整的解决方案,我会将其作为答案发布。 – Ralph