我想做單元測驗并檢查日期是否為閏年,在這種情況下我如何應用單元測驗,我不知道在這種情況下如何進行?
我已經創建了我的函式并且它作業正常,我還有一個 JSON 檔案,其中包含人員串列及其生日日期!
希望得到一些關于如何解決這個問題的反饋或建議!謝謝
BD.go:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"time"
)
// Users struct which contains
// an array of users
type Users struct {
Users []User `json:"users"`
}
// User struct which contains a name
// a type and a list of social links
type User struct {
Firstname string `json:"fname"`
Secondname string `json:"lname"`
Date string `json:"date"`
}
var users Users
var user User
func 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)
}
}
// check if the date is a leap year, ex: 29 is not a leap year but 28th is !
if date.Day()%400 == 0 || (date.Day()%4 == 0 && date.Day()%100 != 0) {
fmt.Println("User First Name: " users.Users[i].Firstname)
fmt.Println("User Second Name: " users.Users[i].Secondname)
fmt.Println("User Date: " users.Users[i].Date)
fmt.Println(users.Users[i].Date, "is a Leap Year ? ? ?")
// checking if the date.day matches today's date
if date.Day() == time.Now().Day() {
fmt.Println("User First Name: " users.Users[i].Firstname)
fmt.Println("User Date: " users.Users[i].Date)
fmt.Println("TODAY IS YOUR BIRTHDAY, Happy birthday !!!?? ?? ?? ?? ")
// not ur birthday today because the date in the json doesn't match todays date
} else {
fmt.Println("TODAY IS NOT YOUR BIRTHDAY..!!!")
}
} else {
fmt.Println("User First Name: " users.Users[i].Firstname)
fmt.Println("User Second Name: " users.Users[i].Secondname)
fmt.Println("User Date: " users.Users[i].Date)
fmt.Println(users.Users[i].Date, " is Not a Leap Year ?? ?? ?? ")
}
}
return false
}
func main() {
Birthday()
}
bd_test.go:
package main
import (
"testing"
)
//*** Addition ***
type dateTest struct {
fname, lname, date string
}
var dateTests = []dateTest{
{"Mario", "terry", "2001/09/28"},
{"neno", "torres", "2001/14/44"}, // should display an error
{"harry", "potter", "2011/10/02"},
}
func TestingDates(t *testing.T) {
for _, test := range dateTests {
if output := Birthday();
output != test.expected {
t.Errorf("Output %q not equal to expected %q", output, test.expected)
}
}
}
用戶.JSON:
{
"users": [
{
"Fname": "Johnny",
"Lname":"mane",
"date":"1982/01/08"
},
{
"Fname": "Wayne",
"Lname":"Bruce",
"date":"1965/01/30"
},
{
"Fname": "Gaga",
"Lname":"Lady",
"date":"1986/03/08"
},
{
"Fname": "radio",
"Lname":"head",
"date":"1988/02/29"
},
{
"Fname": "Mario",
"Lname":"torres",
"date":"1996/09/04"
},
{
"Fname": "robert",
"Lname":"Alex",
"date":"1991/12/05"
},
{
"Fname": "Julia",
"Lname":"sevak",
"date":"1991-03-28"
},
{
"Fname": "feb",
"Lname":"robert",
"date":"1995-05-24"
},
{
"Fname": "Liam",
"Lname":"Noah",
"date":"2002-10-04"
},
{
"Fname": "alex",
"Lname":"sam",
"date":"2021/10/21"
}
}
]
}
uj5u.com熱心網友回復:
您的代碼需要進行一些重構以使其可測驗。目前您無法真正測驗代碼,因為代碼中的函式不回傳任何內容。在單元測驗中,您呼叫一個函式并驗證它的輸出(一般來說)。
因此,為了使您的代碼可測驗,您必須在單獨的函式中重構代碼的某些部分。我將向您展示閏年的示例:
//main.go
func IsLeapYear(date time.Time) bool {
if date.Year() % 400 == 0 {
return true
}
return date.Year()%4 == 0 && date.Year()%100 != 0
}
在您的測驗檔案中:
//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)
}
}
uj5u.com熱心網友回復:
關于您更新的代碼:
我將從我給您的最重要的一條建議開始: 停止忽略錯誤!檢查錯誤對于除錯 Go 代碼和運行程式絕對至關重要。請記住,與許多高級語言(如 Javascript)不同,Go 中沒有例外。您對錯誤回傳的檢查是您必須捕獲這些錯誤的唯一機會。
例如:
json.Unmarshal(byteValue, &users)
如果 json 無效,該行將回傳錯誤。你應該檢查一下。查找有關您使用的每個庫函式的檔案,但您沒有記住 - 我是這樣做的 - 并確保您正在使用這些錯誤訊息。
好的,讓我們看看你傳遞給什么IsLeapYear:
jsonFile, err := os.Open("users.json")
...
IsLeapYear("users.json")
當你到達時,IsLeapYear你已經過了需要檔案名的地方。您已經打開該檔案并將其值解組為Users結構體。所以你當然不需要將檔案名傳遞給它。
讓我強調 Pim 向您展示的一些您沒有忠實遵守的內容:
func IsLeapYear(date time.Time) bool
Pim'sIsLeapYear檢查一個日期這一事實很重要。您的測驗用例是需要單獨檢查的單獨日期。但是您 IsLeapYear會遍歷整個日期串列。您不能提供要檢查的特定日期。您的閏年也希望收到多個日期,但您只回傳一個bool,因此單個回傳值不可能告訴您閏年檢查您可能已通過的多個日期中的每一個的結果。
遵循 Pim 的建議IsLeapYear- 它應該只有一個引數,并且應該是一個time.Time. 名字和姓氏不相關,IsLeapYear因此不需要傳遞。 IsLeapYear不需要決議日期 - 它們的格式與您在 json 中存盤資料的方式無關,與它們代表的日期是否為閏年無關。
以 10-20 行函式為目標。
我提出這個建議的原因是,長函式幾乎總是做得太多,這表明您需要重構函式以更好地匹配演算法的組件。讓我們將您的代碼分解為偽代碼以更好地反映您的演算法:
- 從 json 檔案中讀取用戶
- 對于每個用戶:
- 從預期格式決議其日期
- 如果是閏年生日
- 列印用戶資訊
- 列印閏年訊息
- 如果生日是今天,列印用戶資訊和生日資訊
- 否則列印不是生日訊息
- 否則列印用戶資訊而不是生日資訊
從中我們可以確定我們可能撰寫的一些函式:
func ReadUsersFromJson(filename string) (*Users, err)func ParseUserDateString(date string) (time.Time, error)func IsLeapYear(date time.Time) boolfunc PrintUserInfo(u User)func IsTodaysDate(date time.Time) bool
這些函式中的每一個都非常直接和簡短,并且只做一件事。它們中的每一個都可以依次進行測驗。您的一般測驗方法很常見:撰寫完整的輸入串列(和預期輸出- 您錯過了那部分),然后遍歷串列,將每個輸入傳遞給被測驗的函式,并驗證其結果是否符合您的要求預期的。
因為ReadUsersFromJson您可以有一個tests/目錄,其中包含您測驗的一些 json 檔案。您可以使用有效和無效的 json 測驗成功和錯誤情況。
Similarly, ParseUserDateString test data might look something like:
struct ParseUserDateStringTestData {
input string
expected time.Time
exp_err_msg string
}
Then you can test both success and failure cases there. And so on for the rest of the functions.
Once all the functions are written and tested, it's just a question of assembling all the functions together in 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!")
}
}
}
It just so happens to come in at 20 lines, and it also is quite clear what it's doing. You'll notice that since I wrote PrintUserInfo it removed a bunch of duplication in Birthday. This duplication makes the function harder to read and manage of course.
If you write functions like the ones I lay out, and test all of them, your program should come together nicely. Notice that main() or Birthday() do not need to be written to test the other functions. It's a good idea to test your functions as you write them, so as not to end up with a huge backlog of tests, and to instill confidence in the code you've written.
Case in point:
if date.Day() == time.Now().Day() {
I don't think that's doing what you think it's doing. Day() is actually the day of the month, so you're actually just saying, is the day of the date the same day of the month as today's day? The 29th of any month would be the same Day() as the 29th of February. Testing would prove whether or not this was the case, then you could rely on that functionality later.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/335574.html
下一篇:c#遞回查找最大值(最快)
