我正在嘗試創建一個模擬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