5

なんらかの理由で、属性を介してテストに引数を渡すとTestCase、最初の引数 (この場合は配列) に関する次のエラー メッセージが表示されます。

これは有効な定数式またはカスタム属性値ではありません

module GameLogicTest = 
    open FsUnit
    open NUnit.Framework
    open GameLogic.Examle

    // This is not a valid constant expression or custom attribute value
    [<TestCase( [| 1; 2; 3 |], 3, 1,1)>]
    let ``let example.`` (a, m, h, c) = 
        a
        |> proof1 m
        |> should equal (h,c)

しかし、属性とメソッド自体の両方から最後の引数を削除すると、すべて正常に機能します。

[<TestCase( [| 1; 2; 3 |], 3, 1)>]
let ``let example.`` (a, m, h) = 
    a
    |> proof1 m
    |> should equal (h,1)

私は何を間違っていますか?できればタプルも定義したいのですint * intが、どちらもうまくいかないようです。

4

2 に答える 2

5

CLI には、属性パラメーターの種類に関する制限があります。

  • プリミティブ: bool、int、float など
  • 列挙
  • 文字列
  • 型参照: System.Type
  • 'kinda objects': 上記の型のボックス化された (必要な場合) 表現
  • 上記のいずれかのタイプの 1 次元配列 (つまり、ネストされた配列は許可されません)

したがって、この時点で、タプルを属性パラメーターの型として使用できないと結論付けることができます。

ここから私の推測が始まりますので、以下のどれも真実ではありません.

さまざまな属性で少し遊んだところ、属性に可変数の引数 (params) がある場合、F# コンパイラがすべての配列パラメーターについて不平を言うことがわかりました。たとえば、次の属性を定義すると

public class ParamsAttribute : Attribute
{
    public ParamsAttribute(params object[] parameters)
    {}
}

F# コードから使用しようとすると、エラーが発生します。

[<Params(1, 2, 3)>] // here everything is OK
let x () = ()

[<Params([|1; 2; 3|])>] // the same error as you have
let y () = ()

コンパイラは params 引数を配列と見なすことができるため、「ネストされた」配列をその中に定義することはできません。しかし、私が言ったように、それは純粋な憶測です。

于 2015-01-18T22:32:43.817 に答える
1

配列パラメーターの代わりに文字列パラメーターを使用します。すべての用語を文字列に連結して渡します。String.Split を使用して文字列パラメーターを文字列配列Array.mapに変換し、使用して選択した配列に変換します。

[<TestCase([|1, 2, 3|], 4, 5, 6)>]
let ``My Test``(param1: int[], param2: int, param3: int, param4: int) =
    // My test code

なる

[<TestCase("1|2|3", 4, 5, 6)>]
let ``My Test``(param1: string, param2: int, param3: int, param4: int) =
    let stringArray = param1.Split('|', SplitStringOptions.None)
    let intArray = Array.map int stringArray

    // My test code
于 2015-11-11T08:11:24.250 に答える