【问题标题】:GAE Go tests - do datastore queries work in test environment?GAE Go 测试 - 数据存储查询是否在测试环境中工作?
【发布时间】:2014-08-01 07:16:54
【问题描述】:

最近我开始编写一些测试,用于在我的 Google App Engine Go 应用程序中发送电子邮件。电子邮件发送过程的一部分是使用此功能将电子邮件保存在数据存储中:

func PutInDatastoreFull(c appengine.Context, kind, stringID string, intID int64, parent *datastore.Key, variable interface{}) (*datastore.Key, error) {
    k := datastore.NewKey(c, kind, stringID, intID, parent)
    key, err := datastore.Put(c, k, variable)
    return key, err
}

我的测试使用这个函数查询数据存储:

func QueryGetAllWithLimit(c appengine.Context, kind string, limit int, dst interface{}) ([]*datastore.Key, error) {
    q := datastore.NewQuery(kind).Limit(limit)
    return q.GetAll(c, dst)
}

当我在开发环境中运行它时,它会毫无问题地返回最后一封电子邮件。但是,当我使用goapp test 运行它时,它不会返回任何错误和数据。这是测试环境的预期行为,还是我只是发现了一些错误?

编辑:

测试是:

//Testing file
func TestEmails(t *testing.T) {
    c, err := aetest.NewContext(nil)
    if err != nil {
        t.Fatal(err)
    }
    defer c.Close()

    err := NotifyAdminOfLowBalance(c, []string{"WARNING1", "WARNING2"})
    if err != nil {
        t.Fatal(err)
    }
    emails, err := Data.LoadLastEmails(c, 100)
    if err != nil {
        t.Fatal(err)
    }
    if len(emails) == 0 { //test fails here
        t.Fatal("len(emails)==0")
    }
}

//Production code
func NotifyAdminOfLowBalance(c appengine.Context, warnings []string) error {
    not := Notification{}
    not.Warnings = warnings

    buff := new(bytes.Buffer)
    err := LowBalanceTemplate.Execute(buff, not);
    if err != nil {
        c.Errorf("Backend Notifications - NotifyAdminOfLowBalance - error 1 - %v", err)
        return err
    }
    emailBody := buff.String()
    c.Debugf("Backend Notifications - emailBody - %v", emailBody)
    emailSubject := "Low balance!"
    err = Email.SendHTMLEmail(c, emailSubject, DEFINE.AdminEmails, DEFINE.EmailSender, emailBody)
    if err != nil {
        c.Errorf("Backend Notifications - NotifyAdminOfLowBalance - error 2 - %v", err)
        return err
    }
    err = Data.CreateAndSaveEmail(c, emailBody, emailSubject, "ADMIN", "", "", "")
    if err != nil {
        c.Errorf("Backend Notifications - NotifyAdminOfLowBalance - error 3 - %v", err)
        return err
    }
    return nil
}



//Data/Email.go file:
var EmailStr string = "Email"

type Email struct {
    //Class for handling Emails of what is happening in the system
    EmailID           string //ISO date?
    Timestamp         time.Time
    Body              string `datastore:"-"`
    BodyByte          []byte
    Subject           string
    UserEmail         string
    RippleTxID        string
    CoinTxID          string
    Currency          string
}

func (l *Email) LoadStrings() {
    l.Body = mymath.Hex2ASCII(l.BodyByte)
}

func CreateAndSaveEmail(c appengine.Context, body, subject, userEmail, rippleTx, coinTx, currency string) error {
    email := new(Email)
    email.Timestamp = time.Now()
    email.EmailID = email.Timestamp.Format("2006-01-02T15:04:05:")+mymath.Int2Str(email.Timestamp.Nanosecond())
    email.Body = body
    email.BodyByte = mymath.ASCII2Hex(body)
    email.Subject = subject
    email.UserEmail = userEmail
    email.RippleTxID = rippleTx
    email.CoinTxID = coinTx
    email.Currency = currency

    keys, err := Datastore.PutInDatastoreFull(c, EmailStr, email.EmailID, 0, nil, email)
    c.Debugf("keys - %v, err - %v", keys, err)
    if err != nil {
        c.Errorf("Email - CreateAndSaveEmail error 1 - %v", err)
        return err
    }
    return nil
}

func LoadLastEmails(c appengine.Context, count int) ([]Email, error) {
    c.Debugf("LoadLastEmails - %v", count)
    dst := []Email{}
    keys, err := Datastore.QueryGetAllWithLimit(c, EmailStr, count, &dst)
    c.Debugf("keys - %v, err - %v", keys, err)
    if err != nil {
        c.Errorf("Email - LoadLastEmails error 1 - %v", err)
        return nil, err
    }
    c.Debugf("dst - %v", dst)
    return dst, nil
}

上面已经包含了 Datastore 函数

【问题讨论】:

  • 您定义了任何测试吗?
  • 你能告诉我们测试本身的代码吗?
  • @fabrizioM 添加了测试代码
  • @OneOfOne 添加了测试代码

标签: google-app-engine testing go google-cloud-datastore


【解决方案1】:

我也遇到了这个问题,我相信这是因为您正在执行跨组查询并且尚未应用写入。如果我在之后进行 put 然后查询,我也能够使用开发服务器重现此问题。我理解这是当您不在事务或实体组中时开发服务器如何模拟类似于生产的写入可见性。 IOW,我认为它正在正常工作。

在调用之间添加睡眠(一个坏主意)或对之前在测试中更改/创建的任何实体执行 get() 将使它们显示在查询中。

有关写入和数据可见性规则,请参阅:https://developers.google.com/appengine/docs/go/datastore/#Go_Datastore_writes_and_data_visibility

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 2014-06-27
    相关资源
    最近更新 更多