2015-12-25 7 views
7

अस्वीकरण के लिए "एफएमटी" गोलांग लाइब्रेरी पैकेज से निपटने का तरीका अस्वीकरण: मैं आपको एक सुखद एक्समास की कामना करता हूं और मुझे उम्मीद है कि मेरा प्रश्न आपको परेशान नहीं करेगा!सीएलआई परीक्षण

sample.go:

package main 

import(
    "fmt" 
    "os" 
) 


type sample struct { 
    value int64 
} 

func (s sample) useful() { 
    if s.value == 0 { 
     fmt.Println("Error: something is wrong!") 
     os.Exit(1) 
    } else { 
     fmt.Println("May the force be with you!") 
    } 
} 

func main() { 
    s := sample{42} 
    s.useful() 

    s.value = 0 
    s.useful() 
} 

// output: 
// May the force be with you! 
// Error: something is wrong! 
// exit status 1 

मैं कैसे golang परीक्षण में इंटरफेस का उपयोग करने पर अनुसंधान के एक बहुत था। लेकिन अब तक मैं अपने सिर को पूरी तरह से लपेट नहीं पा रहा था। कम से कम मैं नहीं देख सकता कि जब मुझे "नकली" (इस शब्द का उपयोग करने के लिए माफ़ी) गोलांग std की आवश्यकता होती है तो इंटरफेस मेरी मदद कैसे करते हैं। लाइब्रेरी पैकेज जैसे "एफएमटी"।

  1. उपयोग ओएस/कार्यकारी कमांड लाइन इंटरफेस का परीक्षण करने के
  2. रैप fmt पैकेज तो मैं नियंत्रण है और उत्पादन की जाँच करने में सक्षम हूँ:

    मैं दो स्थितियों के साथ आया था तार

मुझे दोनों परिदृश्य पसंद नहीं हैं:

  1. मुझे वास्तविक कमांड लाइन के माध्यम से एक ठोस और निष्पादक (नीचे देखें) के माध्यम से जाने का अनुभव होता है। पोर्टेबिलिटी के मुद्दे भी हो सकते हैं।
  2. मेरा मानना ​​है कि यह जाने का तरीका है, लेकिन मुझे डर है कि एफएमटी पैकेज को लपेटना बहुत काम हो सकता है (कम से कम परीक्षण के लिए समय पैकेज को एक गैर-तुच्छ कार्य (https://github.com/finklabs/ttime) को बदलने के लिए लपेटना)।

वास्तविक प्रश्न यहां: क्या कोई और (बेहतर/सरल/मूर्खतापूर्ण) तरीका है? नोट: मैं इसे शुद्ध गोलांग में करना चाहता हूं, मुझे अगले परीक्षण ढांचे में दिलचस्पी नहीं है।

cli_test.go:

package main 

import(
    "os/exec" 
    "testing" 
) 


func TestCli(t *testing.T) { 
    out, err := exec.Command("go run sample.go").Output() 
    if err != nil { 
     t.Fatal(err) 
    } 
    if string(out) != "May the force be with you!\nError: this is broken and not useful!\nexit status 1" { 
     t.Fatal("There is something wrong with the CLI") 
    } 
} 

उत्तर

8

Kerningham की पुस्तक के अध्याय 11 इस सवाल का एक अच्छा समाधान देता है। चाल fmt.Fprint (बाहर, ...) जहां बाहर os.Stdout

यह नया करने के लिए परीक्षण दोहन में ओवरराइट किया जा सकता करने के लिए initialised है करने के लिए कॉल करने के लिए fmt.Printline() के लिए कॉल को बदलने के लिए है (बाइट्स बफर) आउटपुट कैप्चर करने के लिए परीक्षण की इजाजत देता है।

package main 


import(
    "fmt" 
    "os" 
    "io" 
) 


var out io.Writer = os.Stdout // modified during testing 
var exit func(code int) = os.Exit 

type sample struct { 
    value int64 
} 


func (s sample) useful() { 
    if s.value == 0 { 
     fmt.Fprint(out, "Error: something is wrong!\n") 
     exit(1) 
    } else { 
     fmt.Fprint(out, "May the force be with you!\n") 
    } 
} 


func main() { 
    s := sample{42} 
    s.useful() 

    s.value = 0 
    s.useful() 
} 

// output: 
// May the force be with you! 
// Error: this is broken and not useful! 
// exit status 1 

cli_test.go:

https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo.go और https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo_test.go

ओपी द्वारा संपादित ... sample.go देखें

package main 

import(
    "bytes" 
    "testing" 
) 


func TestUsefulPositive(t *testing.T) { 
    bak := out 
    out = new(bytes.Buffer) 
    defer func() { out = bak }() 

    s := sample{42} 
    s.useful() 
    if out.(*bytes.Buffer).String() != "May the force be with you!\n" { 
     t.Fatal("There is something wrong with the CLI") 
    } 

} 


func TestUsefulNegative(t *testing.T) { 
    bak := out 
    out = new(bytes.Buffer) 
    defer func() { out = bak }() 
    code := 0 
    osexit := exit 
    exit = func(c int) { code = c } 
    defer func() { exit = osexit }() 

    s := sample{0} 
    s.useful() 
    if out.(*bytes.Buffer).String() != "Error: something is wrong!\n" { 
     t.Fatal("There is something wrong with the CLI") 
    } 
    if code != 1 { 
     t.Fatal("Wrong exit code!") 
    } 
} 
+0

वाह पर एक नज़र डालें, मुझे नहीं पता था कि पाईक एक पुस्तक लिखी। क्या आप शीर्षक या पुस्तक के संदर्भ को बता सकते हैं। मुझे आपकी सलाह पसंद है। मैं इस तरह अपने कोड को दोबारा करने और वापस रिपोर्ट करने जा रहा हूं। आपको बहुत - बहुत धन्यवाद! – mark

+1

गो प्रोग्रामिंग भाषा http://www.gopl.io/ एलन ए। डोनोवन · ब्रायन डब्ल्यू। केर्निजन प्रकाशित 26 अक्टूबर, 2015 पेपरबैक में और 20 नवंबर में ई-बुक एडिसन-वेस्ले; 380pp; आईएसबीएन: 978-0134190440 – Amnon

+0

मैंने आपकी सलाह के बाद कोड को दोबारा प्रतिक्रिया दी। मुझे उम्मीद है कि आपको कोई फर्क नहीं पड़ता कि मैंने यह स्पष्ट करने के लिए आपके उत्तर में जो कुछ भी आया था, मैंने जोड़ा। अगर मैंने कुछ गलत समझा तो कृपया इसे बदलें। वैसे भी os.Exit के साथ एक समस्या प्रतीत होता है। – mark

2

मुझे याद आ रही कुछ यहाँ या आप कर रहे हैं testable examples की बात कर रहे हैं?

असल में, यह इस तरह से काम करता है: एक *_test.go फ़ाइल में आप सम्मेलन Example[[T][_M]] जहां T प्रकार के लिए एक प्लेसहोल्डर और M विधि आप में उदाहरण कोड के रूप में परीक्षण योग्य उदाहरण प्रदर्शित करना चाहते हैं के लिए प्लेसहोल्डर है का पालन करने की जरूरत है गोडोक अगर फ़ंक्शन को केवल Example() कहा जाता है, तो कोड को पैकेज उदाहरण के रूप में दिखाया जाएगा।

अपने उदाहरण के कोड की अंतिम पंक्ति के नीचे, आप यह सुनिश्चित करें कि परीक्षण योग्य उदाहरण समारोह या तो बिल्कुल बाहर सब कुछ // Output: नीचे डालता है कर देगा इस

// Output: 
// Foo 

अब go test की तरह एक टिप्पणी डाल सकते हैं (व्हाइटस्पेस समेत) या यह परीक्षण विफल हो जाएगा।

यहाँ एक परीक्षण योग्य उदाहरण

func ExampleMongoStore_Get() { 

    sessionId := "ExampleGetSession" 

    data, err := ms.Get(sessionId) 

    if err == sessionmw.ErrSessionNotFound { 

    fmt.Printf("Session '%s' not found\n", sessionId) 

    data = make(map[string]interface{}) 
    data["foo"] = "bar" 

    ms.Save(sessionId, data) 
    } 

    loaded, _ := ms.Get(sessionId) 
    fmt.Printf("Loaded value '%s' for key '%s' in session '%s'", 
    loaded["foo"], 
    "foo", sessionId) 
    // Output: 
    // Session 'ExampleGetSession' not found 
    // Loaded value 'bar' for key 'foo' in session 'ExampleGetSession' 
} 

संपादित करने के लिए एक वास्तविक उदाहरण है: the output of above example at godoc.org