第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

我如何應(yīng)用單元測(cè)試來(lái)檢查 golang 的閏年?

我如何應(yīng)用單元測(cè)試來(lái)檢查 golang 的閏年?

Go
江戶川亂折騰 2022-10-10 15:38:41
我想做單元測(cè)試并檢查日期是否是閏年,在這種情況下我如何應(yīng)用單元測(cè)試,我不知道在這種情況下該怎么做?我已經(jīng)創(chuàng)建了我的函數(shù)并且工作正常,我還有一個(gè) JSON 文件,其中包含人員列表及其生日日期!希望能提供一些有關(guān)如何解決此問(wèn)題的反饋或建議!謝謝BD.go: package mainimport (    "encoding/json"    "fmt"    "io/ioutil"    "log"    "os"    "time")// Users struct which contains// an array of userstype Users struct {    Users []User `json:"users"`}// User struct which contains a name// a type and a list of social linkstype User struct {    Firstname  string `json:"fname"`    Secondname string `json:"lname"`    Date       string `json:"date"`}var users Usersvar user Userfunc Birthday() {    // Open our jsonFile    jsonFile, err := os.Open("users.json")    // if we os.Open returns an error then handle it    if err != nil {        fmt.Println(err)    }    fmt.Println("Successfully Opened users.json")    // defer the closing of our jsonFile so that we can parse it later on    defer jsonFile.Close()    // read our opened xmlFile as a byte array.    byteValue, _ := ioutil.ReadAll(jsonFile)    // we initialize our Users array    // we unmarshal our byteArray which contains our    // jsonFile's content into 'users' which we defined above    json.Unmarshal(byteValue, &users)    IsLeapYear("users.json")}func IsLeapYear(user string) bool {    // we iterate through every user within our users array and    // print out the user Type, their name    for i := 0; i < len(users.Users); i++ {        date, err := time.Parse("2006/01/02", users.Users[i].Date)        if err != nil {            date, err = time.Parse("2006-01-02", users.Users[i].Date)            // date, err = time.Parse("2006 01 02", users.Users[i].Date)            if err != nil {                log.Fatal("unsupported date format:", err)            }        }
查看完整描述

2 回答

?
森欄

TA貢獻(xiàn)1810條經(jīng)驗(yàn) 獲得超5個(gè)贊

您的代碼需要進(jìn)行一些重構(gòu)以使其可測(cè)試。目前您無(wú)法真正測(cè)試代碼,因?yàn)榇a中的函數(shù)不返回任何內(nèi)容。在單元測(cè)試中,您調(diào)用一個(gè)函數(shù)并驗(yàn)證它的輸出(一般來(lái)說(shuō))。


因此,為了使您的代碼可測(cè)試,您必須在單獨(dú)的函數(shù)中重構(gòu)代碼的某些部分。我將向您展示閏年的示例:


//main.go

func IsLeapYear(date time.Time) bool {

  if date.Year() % 400 == 0 {

    return true

  }

  return date.Year()%4 == 0 && date.Year()%100 != 0

}

在您的測(cè)試文件中:


//main_test.go

type dateTest struct {

  date time.Time

  expect bool

}


var dateTests = []dateTest{

  // your test data

}


func TestIsLeapYear(t *testing.T){

  for _, tc := range dateTests {

    result := IsLeapYear(tc.data)

    assert.Equal(t, tc.expect, result)

  }

}


查看完整回答
反對(duì) 回復(fù) 2022-10-10
?
胡子哥哥

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超6個(gè)贊

關(guān)于您更新的代碼:

我將從我給您的最重要的一條建議開(kāi)始: 停止忽略錯(cuò)誤!檢查錯(cuò)誤對(duì)于調(diào)試 Go 代碼和運(yùn)行程序絕對(duì)至關(guān)重要。請(qǐng)記住,與 Javascript 等許多高級(jí)語(yǔ)言不同,Go 沒(méi)有例外。您對(duì)錯(cuò)誤返回的檢查是您必須捕獲這些錯(cuò)誤的唯一機(jī)會(huì)。

例如:

    json.Unmarshal(byteValue, &users)

如果 json 無(wú)效,該行將返回錯(cuò)誤。你應(yīng)該檢查一下。查找您使用的每個(gè)庫(kù)函數(shù)的文檔,但您沒(méi)有記住 - 我會(huì) - 并確保您正在使用這些錯(cuò)誤消息。

好的,讓我們看看你傳遞給什么IsLeapYear

    jsonFile, err := os.Open("users.json")
    ...
    IsLeapYear("users.json")

當(dāng)你到達(dá)時(shí),IsLeapYear你已經(jīng)過(guò)了需要文件名的地步。您已經(jīng)打開(kāi)了該文件并將其值解組為一個(gè)Users結(jié)構(gòu)。因此,您當(dāng)然不需要將文件名傳遞給它。

讓我強(qiáng)調(diào)一下 Pim 向您展示的一些您沒(méi)有忠實(shí)遵循的內(nèi)容:

func IsLeapYear(date time.Time) bool

IsLeapYearPim檢查一個(gè)日期這一事實(shí)很重要。您的測(cè)試用例是需要單獨(dú)檢查的單獨(dú)日期。但是 IsLeapYear會(huì)遍歷整個(gè)日期列表。您無(wú)法提供要檢查的特定日期。您的閏年還希望收到多個(gè)日期,但您只返回一個(gè)bool,因此單個(gè)返回值不可能告訴您閏年檢查您可能已經(jīng)過(guò)去的多個(gè)日期的結(jié)果。

按照 Pim 的建議IsLeapYear- 它應(yīng)該只有一個(gè)參數(shù),并且應(yīng)該是time.Time. 名字和姓氏不相關(guān),IsLeapYear因此不需要傳遞。 IsLeapYear不需要解析日期 - 它們的格式與您在 json 中存儲(chǔ)數(shù)據(jù)的方式有關(guān),并且與它們所代表的日期是否是閏年無(wú)關(guān)。

瞄準(zhǔn) 10-20 行功能。

我提出這個(gè)建議的原因是,長(zhǎng)函數(shù)幾乎總是做太多事情,這表明您需要重構(gòu)函數(shù)以更好地匹配算法的組件。讓我們將您的代碼分解為偽代碼以更好地反映您的算法:

  • 從 json 文件中讀取用戶

  • 對(duì)于每個(gè)用戶:

    • 打印用戶信息

    • 打印閏年消息

    • 如果生日是今天,打印用戶信息和生日信息

    • 否則打印不是生日信息

    • 從預(yù)期格式解析其日期

    • 如果是閏年生日

    • 否則打印用戶信息而不是生日信息

從中我們可以確定我們可能編寫的一些函數(shù):

  • func ReadUsersFromJson(filename string) (*Users, err)

  • func ParseUserDateString(date string) (time.Time, error)

  • func IsLeapYear(date time.Time) bool

  • func PrintUserInfo(u User)

  • func IsTodaysDate(date time.Time) bool

這些功能中的每一個(gè)都非常簡(jiǎn)單明了,而且只做一件事。它們中的每一個(gè)都可以依次進(jìn)行測(cè)試。你的一般測(cè)試方法很常見(jiàn):寫一個(gè)完整的輸入列表(和預(yù)期的輸出- 你錯(cuò)過(guò)了那部分),然后遍歷列表,將每個(gè)輸入傳遞給正在測(cè)試的函數(shù),并驗(yàn)證它的結(jié)果是你的預(yù)期的。

因?yàn)?code>ReadUsersFromJson您可能有一個(gè)tests/目錄,其中包含您測(cè)試的一些 json 文件。您可以使用有效和無(wú)效的 json 測(cè)試成功和錯(cuò)誤情況。

同樣,ParseUserDateString測(cè)試數(shù)據(jù)可能類似于:


struct ParseUserDateStringTestData {

  input string

  expected time.Time

  exp_err_msg string

}

然后你可以在那里測(cè)試成功和失敗的案例。其余的功能依此類推。


一旦所有的功能都被編寫和測(cè)試了,這只是一個(gè)將所有功能組裝在一起的問(wèn)題Birthday()。


func Birthday() {

   users, err := ReadUsersFromJson("users.json")

   if err != nil {

     panic(fmt.Errorf("Failed to read from Json: %w", err))

   }

   for _, user := range users.Users {

      if d, err := ParseUserDateString(user.Date); err != nil {

         panic(fmt.Errorf("Date %s could not be parsed: %w", user.Date, err))

      } else if IsLeapYear(d) {

         PrintUserInfo(user)

         fmt.Printf("Leap year message!")

         if IsTodaysDate(d) {

           fmt.Printf("birthday message!")

         } else {

           fmt.Printf("Not birthday message!")

         }

      } else {

         fmt.Printf("Not leap year message!")

      }

   }

}

它恰好出現(xiàn)在 20 行,而且它在做什么也很清楚。您會(huì)注意到,自從我編寫它以來(lái),PrintUserInfo它刪除了Birthday. 當(dāng)然,這種重復(fù)使函數(shù)更難閱讀和管理。


如果您編寫像我列出的那樣的函數(shù),并測(cè)試所有這些函數(shù),那么您的程序應(yīng)該可以很好地結(jié)合在一起。請(qǐng)注意,main()或Birthday()不需要編寫來(lái)測(cè)試其他功能。在編寫函數(shù)時(shí)測(cè)試它們是一個(gè)好主意,以免最終積壓大量測(cè)試,并灌輸對(duì)您編寫的代碼的信心。


一個(gè)例子:


            if date.Day() == time.Now().Day() {

我不認(rèn)為那正在做你認(rèn)為它正在做的事情。 Day()實(shí)際上是月份的日期,所以你實(shí)際上只是說(shuō),日期的日期與今天的日期是同一天嗎?任何一個(gè)月Day()的 29 日都與 2 月 29 日相同。測(cè)試將證明是否是這種情況,然后您可以稍后依賴該功能。同樣,ParseUserDateString測(cè)試數(shù)據(jù)可能類似于:


struct ParseUserDateStringTestData {

  input string

  expected time.Time

  exp_err_msg string

}

然后你可以在那里測(cè)試成功和失敗的案例。其余的功能依此類推。


一旦所有的功能都被編寫和測(cè)試了,這只是一個(gè)將所有功能組裝在一起的問(wèn)題Birthday()。


func Birthday() {

   users, err := ReadUsersFromJson("users.json")

   if err != nil {

     panic(fmt.Errorf("Failed to read from Json: %w", err))

   }

   for _, user := range users.Users {

      if d, err := ParseUserDateString(user.Date); err != nil {

         panic(fmt.Errorf("Date %s could not be parsed: %w", user.Date, err))

      } else if IsLeapYear(d) {

         PrintUserInfo(user)

         fmt.Printf("Leap year message!")

         if IsTodaysDate(d) {

           fmt.Printf("birthday message!")

         } else {

           fmt.Printf("Not birthday message!")

         }

      } else {

         fmt.Printf("Not leap year message!")

      }

   }

}

它恰好出現(xiàn)在 20 行,而且它在做什么也很清楚。您會(huì)注意到,自從我編寫它以來(lái),PrintUserInfo它刪除了Birthday. 當(dāng)然,這種重復(fù)使函數(shù)更難閱讀和管理。


如果您編寫像我列出的那樣的函數(shù),并測(cè)試所有這些函數(shù),那么您的程序應(yīng)該可以很好地結(jié)合在一起。請(qǐng)注意,main()或Birthday()不需要編寫來(lái)測(cè)試其他功能。在編寫函數(shù)時(shí)測(cè)試它們是一個(gè)好主意,以免最終積壓大量測(cè)試,并灌輸對(duì)您編寫的代碼的信心。


一個(gè)例子:


            if date.Day() == time.Now().Day() {

我不認(rèn)為那正在做你認(rèn)為它正在做的事情。 Day()實(shí)際上是月份的日期,所以你實(shí)際上只是說(shuō),日期的日期與今天的日期是同一天嗎?任何一個(gè)月Day()的 29 日都與 2 月 29 日相同。測(cè)試將證明是否是這種情況,然后您可以稍后依賴該功能。


查看完整回答
反對(duì) 回復(fù) 2022-10-10
  • 2 回答
  • 0 關(guān)注
  • 134 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)