ããã«ã¡ã¯ãå°éãããã§ããã¿ã¤ãã«å ¨é¨ã§ãã
æ¨æ¥ãç¾å¨æå»ã«ãã£ã¦æ¡ä»¶åå²ãããã¸ãã¯ãå«ãGoããã°ã©ã ãæ¸ãã¦ãã¦ãã©ããã¹ããããå°ã£ãã®ã§ããããã¾ãï¼ã¨æãï¼ããæ¹ãæãã¤ããã®ã§ããã«æ¸ãã¦ããã¾ãã
æ¸ãã¦ããã®ã¯ã¾ãã ãããããããã½ã¼ã¹ã³ã¼ãã§ãã
// main.go package main import ( "fmt" "time" ) func main() { fmt.Println(Greet("ããã")) } func Greet(n string) string { t := time.Now() if 6 <= t.Hour() && t.Hour() <= 18 { return fmt.Sprintf("ããã«ã¡ã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } else { return fmt.Sprintf("ããã°ãã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } }
go run main.go ããã«ã¡ã¯ããããããä»ã¯12æã§ããï¼
ã§ããã®Greet
é¢æ°ããã¹ãããããã§ããããã®ã¾ã¾ã§ã¯å¤ã®æ¨æ¶ãåºãã®ã«18æã¾ã§å¾
ã¤å¿
è¦ãããã¾ããããã§ã¯å°ãã®ã§time.Now
ã®é¨åããªãã¨ãã¡ããã¾ããã¦ãã¤ã§ãå
¨ã¦ã®æ¡ä»¶ããã¹ãåºæ¥ãããããªãã¨ããã¾ãããããããã¹ã¿ãåã§ããã
ããã«æãæµ®ãã¶ã®ã¯ãGreeté¢æ°ãä¸ã®ããã«DIã£ã½ãä¾åæ§ã§ããç¾å¨æå»ãå¼æ°ããåãåãããã«å¤æ´ããæ¹æ³ã ã¨æãã¾ãã
// main.go func Greet(n string, t time.Time) string { // å¼æ°ã«ç¾å¨æå»ã追å if 6 <= t.Hour() && t.Hour() <= 18 { return fmt.Sprintf("ããã«ã¡ã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } else { return fmt.Sprintf("ããã°ãã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } }
ãããªãä»»æã®æéã®å ´åã®Greeté¢æ°ã®ã¦ããããã¹ããæ¸ãã¾ãããç¾å¨æå»ã®ãã¹ãã®ããã«æ¬æ¥ä¸è¦ãªå¼æ°ãå¢ããã®ã¯å¤§ããã§å¥½ã¾ããããã¾ããï¼å¥½ã¿ã®åé¡ã§ãï¼ãããã«ãçµå±ã³ã¼ã«ã¹ã¿ãã¯ã®ã©ããã§time.Now()
ãå¼ã¶å¿
è¦ãããããã®å¼ã³åºããã¤ã³ããå«ããã¹ãã¯ã¹ã¿ãåã§ãã¾ããã
ããã¯ãã¯ãtime.Nowé¢æ°ããã¹ãå®è¡æã ãåçã«ä¸æ¸ããããã¨ããã§ãããGolangã¯ãã¾ãã¹ã¿ãåã«åªããè¨èªã§ã¯ãªããä¾ãã°timeããã±ã¼ã¸ããã¹ãæã«åçã«ä»ã®ããã±ã¼ã¸ã«å·®ãæ¿ããã¨ãã¯ã§ãã¾ããããããèªä½ããã±ã¼ã¸ã§æä¾ãã¦ããæ§é ä½ããªã«ãã§ããã°ãinterfaceã§ããªãã§ã使ã£ã¦ã¹ã¿ããã«ã«ããã°ããã¨æãã¾ããâ¦ã
ï¼åèï¼go - Is there an easy way to stub out time.Now() globally in golang during test? - Stack Overflowï¼
ã§ãã©ããããã¨ããã¨ãã¿ã¤ãã«éãã§ããmain.goã§time.Nowã®é¢æ°ãã¤ã³ã¿ãã°ãã¼ãã«å¤æ°ã«ä»£å ¥ãã¦ããããã¹ãæã«main_test.goã§ä»»æã®æå»ãè¿ãé¢æ°ã«ãããããã¨ããæ¹æ³ã使ãã¾ããã
// main.go package main import ( "fmt" "time" ) var timeNowFunc = time.Now // é¢æ°ãã°ãã¼ãã«å¤æ°ã«ä»£å ¥ func main() { fmt.Println(Greet("ããã")) } func Greet(n string) string { t := timeNowFunc() // ã°ãã¼ãã«å¤æ°ã§time.Nowé¢æ°ãå¼ã³åºã if 6 <= t.Hour() && t.Hour() <= 18 { return fmt.Sprintf("ããã«ã¡ã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } else { return fmt.Sprintf("ããã°ãã¯%sãããä»ã¯%dæã§ããï¼", n, t.Hour()) } }
Goã¯é¢æ°ãä¸ç´å¸æ°ãªã®ã§ã·ã°ããã£ããåè´ããã°å¤æ°ã«ä»£å
¥ã§ãã¾ãããã®å ´åãtimeNowFunc
å¤æ°ã¯åæ¨è«ã§func() time.Time
åã¨ãã¦å®£è¨ãããtime.Nowé¢æ°ã§åæåããã¾ããã§ãããã次ã®ããã«ãã¹ããã¾ãã
// main_test.go package main import ( "testing" "time" ) const timeformat = "2006-01-02 15:04:06" // timeã®ãã©ã¼ãããæå®æåå // timeNowFuncã°ãã¼ãã«å¤æ°ã®é¢æ°ãå ¥ãæ¿ããé¢æ° func setNow(t time.Time) { timeNowFunc = func() time.Time { return t } } func TestMain(t *testing.T) { evening, _ := time.Parse(timeformat, "2014-08-14 14:10:00") night, _ := time.Parse(timeformat, "2014-08-14 22:30:00") // æ¼ã®ãã¹ã setNow(evening) // ã¹ã¿ãï¼timeNowFuncã«æ¼æå»ãè¿ãé¢æ°ãã»ãã if ret := Greet("ã¾ã¨ãº"); ret != "ããã«ã¡ã¯ã¾ã¨ãºãããä»ã¯14æã§ããï¼" { t.Errorf("Greet Fails. Got [%s]\n", ret) } // å¤ã®ãã¹ã setNow(night) // ã¹ã¿ãï¼timeNowFuncã«æ¼æå»ãè¿ãé¢æ°ãã»ãã if ret := Greet("ã¾ã¨ãº"); ret != "ããã°ãã¯ã¾ã¨ãºãããä»ã¯22æã§ããï¼" { t.Errorf("Greet Fails. Got [%s]\n", ret) } }
$ go test PASS ok _/Users/matope/dev/go/mock 0.006s
ãã¹ãå
ã§å®£è¨ãã¦ããsetNow(time.Time)
é¢æ°ã¯ãã°ãã¼ãã«å¤æ°ã®timeNowFuncã«ãä»»æã®æå»ãè¿ãé¢æ°ã代å
¥ããé¢æ°ã§ããããã§ãã¹ããã¨ã«timeNowFuncã®è¿ãæå»ãã³ã³ããã¼ã«ã§ããã®ã§ãä»»æã®æå»ã®ãã¹ããæ¸ãã¾ãããããé¢åãªã¹ã¿ãç¨ã¯ã©ã¹å®è£
ãä¸è¦ãªå¼æ°ã®å¼ãåããªãã§ããã¹ãæã«ã®ã¿ä½ç¨ããã¹ã¿ãã§ãã
ã°ãã¼ãã«å¤æ°ã¨èãã¦ã¤ãããªã人ãããããããã¾ããããGoã®ã°ãã¼ãã«å¤æ°ã¯å®éã«ã¯ããã±ã¼ã¸ã¹ã³ã¼ãã§ãé æåãå°æåã«ãã¦ããã°ããã±ã¼ã¸ã®å¤ããã¢ã¯ã»ã¹ã§ããªãã®ã§ãæ¯è¼çã¯ãªã¼ã³ã§ããGoã¯ãã¹ããã³ã¼ãã¨åãããã±ã¼ã¸ç©ºéã§å®è¡ã§ããã®ã§ããã¹ãã³ã¼ãã«å¯¾ãã¦ã®ã¿Exportããããã©ã¡ã¼ã¿ã¨ãã¦æ±ãã¾ãã
ãã®ããã¹ãæã«ã¹ã¿ããããé¢æ°ã®å¼ã³åºããã°ãã¼ãã«å¤æ°ã§ãããã·ãã¦ããã¦testå´ã®åæåã§å·®ãæ¿ããæ¹æ³ã¯ãåä¸ããã±ã¼ã¸å
ã§ããã°ã¢ãã¯åã®ããã®è¿½å ã®è¨è¿°éãå°ãªãããã¼ã¿ãã¼ã¹ã®ãã¹ããªã©ãããããå¿ç¨ãå©ãããã ãªã¨æãã¾ãããè¤æ°ããã±ã¼ã¸ã«ã¾ãããtime.Now()
ãä¸æ¬ã§å·®ãæ¿ããããããªå ´åã¯ãã¹ã¿ããããã·ç¨ã®ããã±ã¼ã¸ãä½ã£ã¦ããã®Exported(大æåããå§ã¾ã)ã°ãã¼ãã«å¤æ°ã«ã»ãããã¦ããã°ããããã§ããã
ã¡ãªã¿ã«è±ã§ãããGrouped Globalã使ãã°ãããªæãã§ã¡ãã£ã¨ãã£ãããã°ãã¼ãã«å¤æ°ãå¼ã¹ã¾ãããã¯ãç´ãããããããªæ°ããã¾ããã
// main.go package main import ( "fmt" "time" ) var _time = struct { Now func() time.Time Since func(time.Time) time.Duration }{ time.Now, time.Since, } func main() { fmt.Println(_time.Now()) // â ã¡ãã£ã¨ãã£ããã }
追è¨ï¼åãããæ¹ã解説ãã¦ãè¨äº ããã£ãã®ã§ãã£ã¡èªãã æ¹ããããã