2016-01-27 6 views
6

पर संग्रह कैसे पास करते हैं, मैं xUnit's InlineData के पैरामीटर के रूप में एक सूची, सरणी और/या seq का उपयोग करना चाहता हूं।एफ # में आप xUnit की इनलाइनडेटा विशेषता

सी # में मैं यह कर सकता:

using Xunit; //2.1.0 

namespace CsTests 
{ 
    public class Tests 
    { 
     [Theory] 
     [InlineData(new[] {1, 2})] 
     public void GivenCollectionItMustPassItToTest(int[] coll) 
     { 
      Assert.Equal(coll, coll); 
     } 
    } 
} 

एफ # में मैं इस है:

namespace XunitTests 

module Tests = 
    open Xunit //2.1.0 

    [<Theory>] 
    [<InlineData(8)>] 
    [<InlineData(42)>] 
    let ``given a value it must give it to the test`` (value : int) = 
    Assert.Equal(value, value) 

    [<Theory>] 
    [<InlineData([1; 2])>] 
    let ``given a list it should be able to pass it to the test`` 
    (coll : int list) = 
    Assert.Equal<int list>(coll, coll) 

    [<Theory>] 
    [<InlineData([|3; 4|])>] 
    let ``given an array it should be able to pass it to the test`` 
    (coll : int array) = 
    Assert.Equal<int array>(coll, coll) 

एफ # कोड निम्नलिखित निर्माण त्रुटियों दे:

Library1.fs (13, 16): यह मान्य निरंतर अभिव्यक्ति या कस्टम विशेषता मान

नहीं है

Library1.fs (18, 16): यह एक वैध निरंतर अभिव्यक्ति या कस्टम नहीं है विशेषता मान

2 और 3 परीक्षण सिद्धांतों की चर्चा करते हुए।

क्या इनलाइनडेटा विशेषता में संग्रह में पास करने के लिए xUnit का उपयोग करना संभव है?

+0

धन्यवाद जेम्स, यदि ऐसा है तो लोगों को आम तौर पर एफ # में परीक्षण डेटा के लिए संग्रह की आवश्यकता कैसे होती है? –

+1

मुझे सुझाव दिया गया था कि यह http://stackoverflow.com/questions/29349152/cannot-create-list-literal-in-f का डुप्लिकेट है। हालांकि यह सवाल विशेष रूप से एफ # में एक शाब्दिक सूची बनाने के लिए है (और जवाब है: आप नहीं कर सकते हैं)। यह सवाल है "मैं xUnit का उपयोग कैसे कर सकता हूं और परीक्षण डेटा की सूची में कैसे पास कर सकता हूं"। ऐसा लगता है कि @bytebuster का एक व्यावहारिक उत्तर है। –

+2

आप सूचियों का उपयोग नहीं कर सकते हैं, लेकिन आपको सी # जैसे सरणी का उपयोग करने में सक्षम होना चाहिए, लेकिन मैं इसे संकलित करने में कभी सक्षम नहीं हूं। सौभाग्य से, यह एक बार जब आप खोजते हैं तो यह अप्रासंगिक हो जाता है [FsCheck.Xunit] (https://fscheck.github.io/FsCheck/RunningTests.html)। –

उत्तर

3

InlineDataAttribute सी # params तंत्र पर leans। यह वही है सी # में InlineData के डिफ़ॉल्ट वाक्य रचना के लिए सक्षम बनाता है: -

[InlineData(1,2)] 

सरणी निर्माण के साथ आपका संस्करण: -

[InlineData(new object[] {1,2})] 

क्या संकलक ऊपर करने के लिए अनुवाद बस है। जिस मिनट में आप आगे जाते हैं, आप उसी प्रतिबंध में भाग लेंगे जो सीएलआई वास्तव में सक्षम होगा - नीचे की रेखा यह है कि आईएल स्तर पर, विशेषता रचनाकारों का उपयोग करने का तात्पर्य है कि संकलन समय पर सबकुछ स्थिरांक तक उबाला जाना चाहिए।[<InlineData(1,2)>] है, तो आपके सवाल का सीधा जवाब है: ऊपर वाक्य रचना के एफ # बराबर बस है

module UsingInlineData = 
    [<Theory>] 
    [<InlineData(1, 2)>] 
    [<InlineData(1, 1)>] 
    let v4 (a : int, b : int) : unit = Assert.NotEqual(a, b) 

मैं @ bytebuster के उदाहरण पर riffing से बचने के लिए, हालांकि :) अगर हम एक सहायक को परिभाषित असमर्थ था: -

type ClassDataBase(generator : obj [] seq) = 
    interface seq<obj []> with 
     member this.GetEnumerator() = generator.GetEnumerator() 
     member this.GetEnumerator() = 
      generator.GetEnumerator() :> System.Collections.IEnumerator 

फिर (यदि हम आलस्य छोड़ करने को तैयार हैं), हम list दुरुपयोग seq/yield कोड गोल्फ जीतने के लिए उपयोग करने के लिए होने से बचने के लिए कर सकते हैं: -

type MyArrays1() = 
    inherit ClassDataBase([ [| 3; 4 |]; [| 32; 42 |] ]) 

[<Theory>] 
[<ClassData(typeof<MyArrays1>)>] 
let v1 (a : int, b : int) : unit = Assert.NotEqual(a, b) 

लेकिन seq के कच्चे वाक्य रचना पर्याप्त स्वच्छ बनाया जा सकता है, तो के रूप में ऊपर के लिए इसका इस्तेमाल करने के लिए कोई वास्तविक आवश्यकता है, इसके बजाय हम करते हैं:

let values : obj array seq = 
    seq { 
     yield [| 3; 4 |] 
     yield [| 32; 42 |] 
    } 

type ValuesAsClassData() = 
    inherit ClassDataBase(values) 

[<Theory; ClassData(typeof<ValuesAsClassData>)>] 
let v2 (a : int, b : int) : unit = Assert.NotEqual(a, b) 

हालांकि, ज्यादातर मेरे लिए XUnit v2 के साथ मुहावरेदार सीधे MemberData का उपयोग (जो XUnit v1 के PropertyData की तरह है, लेकिन सामान्यीकृत भी खेतों पर काम करने के लिए) के लिए है: -

[<Theory; MemberData("values")>] 
let v3 (a : int, b : int) : unit = Assert.NotEqual(a, b) 

कुंजी सही होने की बात यह है कि अनुक्रम की घोषणा पर : seq<obj> (या : obj array seq) डालें या xUnit आपको फेंक देगा।

+0

धन्यवाद यह काम करता है, लेकिन एनसीआरंच को सदस्यडेटा पसंद नहीं लगता है। ओ-ठीक है, मैं सबसे अधिक संभावना है कि या तो आगे बढ़ने वाले फैक्ट या एफएस चेक का उपयोग करें। –

+1

क्या यह 'थ्योरी' या 'सदस्य डेटा' पसंद नहीं है? यदि इसका उत्तरार्द्ध है, तो आपको 'प्रॉपर्टीडाटा' काम करने में सक्षम होना चाहिए - बस फ़ील्ड में 'get() 'जोड़ें? आप पर्याप्त विकल्प रखने के बारे में सही हैं - आम तौर पर थ्योरी के प्रत्येक चरण को व्यक्तिगत रूप से संबोधित करने योग्य तथ्य बनाने के लिए पर्याप्त होता है और शायद अधिक पठनीय कोड के साथ समाप्त होता है। –

5

जैसा कि this question में वर्णित है, आप केवल InlineData के साथ अक्षर का उपयोग कर सकते हैं। सूची अक्षर नहीं हैं।

हालांकि, xUnit ClassData प्रदान करता है जो आपको लगता है कि ऐसा करने के लिए लगता है।

This question सी # के लिए एक ही समस्या पर चर्चा करता है।

आदेश परीक्षण के साथ ClassData उपयोग करने के लिए, बस एक डेटा वर्ग को लागू करने seq<obj[]> बनाने में:

type MyArrays() =  
    let values : seq<obj[]> = 
     seq { 
      yield [|3; 4|] // 1st test case 
      yield [|32; 42|] // 2nd test case, etc. 
     } 
    interface seq<obj[]> with 
     member this.GetEnumerator() = values.GetEnumerator() 
     member this.GetEnumerator() = 
      values.GetEnumerator() :> System.Collections.IEnumerator 

module Theories = 
    [<Theory>] 
    [<ClassData(typeof<MyArrays1>)>] 
    let ``given an array it should be able to pass it to the test`` (a : int, b : int) : unit = 
     Assert.NotEqual(a, b) 

इस यद्यपि कुछ मैनुअल कोडिंग की आवश्यकता है, तो आप डेटा वर्ग, जिसमें उपयोगी प्रतीत होता है फिर से उपयोग कर सकते हैं वास्तविक जीवन परियोजनाएं, जहां हम अक्सर एक ही डेटा के खिलाफ अलग-अलग परीक्षण चलाते हैं।

+0

मुझे इस समाधान को काम करने के लिए नहीं मिल रहा है, लेकिन मुझे लगता है कि आप कहां जा रहे हैं और इसे "सही" उत्तर मानते हैं। धन्यवाद, मैं इसे काम करने के बाद इसे सही बना दूंगा। –

+0

सीक {[| 3; 4 |] [| 32; 43 |]} वैध सीक्यू अभिव्यक्ति नहीं है, मैं प्रकार का उपयोग कर समाप्त हुआ MyArrays() = मान = seq [ [| 3; 4 |] // पहला टेस्ट केस [| 32; 42 |] // 2 परीक्षण का मामला, आदि ] |> Seq.cast इंटरफ़ेस seq साथ सदस्य this.GetEnumerator <'T>() = values.GetEnumerator():> System.Collections.Generics.IEnumerator <'T> सदस्य यह। GetEnumerator() = मूल्य। GetEnumerator():> System.Collections.IEnumerator –

+1

@MikeHarris आप अपने suppositions में सही हैं, मैंने दो गायब उपज ऑपरेटरों और एक प्रकार की गलती में संपादित किया है [और एक जवाब सभी पर विस्तार यह नीचे] –

संबंधित मुद्दे