GAE Go测试 - 数据存储区查询在测试环境中工作吗?

时间:2014-06-11 09:32:30

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

最近,我开始编写一些测试,用于在我的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
}

数据存储功能已经包含在上面

1 个答案:

答案 0 :(得分:0)

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

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

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