Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将值传递给接受可为空小数的xUnit测试?_C#_Xunit - Fatal编程技术网

C# 如何将值传递给接受可为空小数的xUnit测试?

C# 如何将值传递给接受可为空小数的xUnit测试?,c#,xunit,C#,Xunit,我的一个单元测试具有以下特征: public void FooWithFilter(string fooId, decimal? amount) 当我用null测试它时,它工作: [InlineData("123", null)] 但如果我使用实际值,例如: [InlineData("123", 610)] 我得到一个错误: System.ArgumentException Object of type 'System.Int32' cannot be converted to type

我的一个单元测试具有以下特征:

public void FooWithFilter(string fooId, decimal? amount)
当我用null测试它时,它工作:

[InlineData("123", null)]
但如果我使用实际值,例如:

[InlineData("123", 610)]
我得到一个错误:

System.ArgumentException Object of type 'System.Int32' cannot be 
converted to type 'System.Nullable`1[System.Decimal]'.
我尝试使用
610M
作为属性值,但不允许将其作为属性值:

An attribute argument must be a constant expression, type of expression
or array creation expression of an attribute parameter type.

有没有办法在此处使用可为空的十进制数?

如注释所示,您不能在此处使用
十进制数,因为
十进制数
不是属性参数值中允许的类型之一

但是,xUnit提供了一种更灵活的方法,使用
ClassData
将参数值传递给测试方法:

[Theory]
[ClassData(typeof(FooDataGenerator))]
public void FooWithFilter(string fooId, decimal? amount)
要使用它,只需定义一个扩展
IEnumerable
并生成所需输入值的类:

public class FooDataGenerator : IEnumerable<object[]>
{
    private readonly List<object[]> _data = new List<object[]>
    {
        new object[] {"123", null},
        new object[] {"123", 610M}
    };

    public IEnumerator<object[]> GetEnumerator() => _data.GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
公共类FooDataGenerator:IEnumerable
{
私有只读列表_data=新列表
{
新对象[]{“123”,null},
新对象[]{“123”,610M}
};
public IEnumerator GetEnumerator()=>\u data.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator()=>GetEnumerator();
}
关于向xUnit测试传递值的各种方法的进一步参考:


除了JLRishe的答案之外,我建议继承
Theroydata
或其通用对手
Theroydata
,这样我们可以得到强类型的测试数据和更干净的代码。我发现文档在这方面有点单薄

[Theory]
[ClassData(typeof(FooDataGenerator))]
public void FooWithFilter(string fooId, decimal? expected)
{
    // Arrange // Act // Assert
}

public class FooDataGenerator : TheoryData<string, decimal?>
{
    public FooDataGenerator()
    {
        this.Add("987", null);
        this.Add("123", 610m);
        // ...
    }
}
[理论]
[ClassData(typeof(FooDataGenerator))]
public void FooWithFilter(字符串fooId,十进制-应为)
{
//安排//Act//Assert
}
公共类FooDataGenerator:TheoryData
{
公共数据生成器()
{
本条加上(“987”,空);
本条添加(“123”,610m);
// ...
}
}

解决这个问题的一个简单方法是将参数设置为两倍?并将其转换为十进制?像这样

[Theory]
        [InlineData(1200, 1150, 50, 100)]
        [InlineData(1200.50, 1200.50, 0, 0)]
        [InlineData(1250.50, 1150, 0, 100.50)]
        [InlineData(1150, 1150, null, null)]
        [InlineData(0, null, null, null)]
        [InlineData(-50, null, 50, null)]
        [InlineData(50, null, null, 50)]

        public void SubTotal(double valorEsperado, double? valorTotal, double? valorFrete, double? valorDesconto) =>
            Assert.Equal((decimal)valorEsperado, PedidoBuilderTest.New
                                            .AtribuirValores((decimal?)valorTotal, (decimal?)valorFrete, (decimal?)valorDesconto)
                                            .Build().SubTotal);

@Igor I get
[CS0182]属性参数必须是常量表达式,属性参数类型的typeof表达式或数组创建表达式
属性只能包含“基元类型”。不幸的是,
Decimal
不是基元类型。属性初始化数据有严格的限制,值必须存储在程序集元数据中,并且只支持简单类型。没错,不支持十进制,CLR对此知之甚少。你得用双翼或弦翼。为什么单元测试需要一个属性来调用方法并不明显。我想您可以接受一个字符串,然后在运行时将其解析为属性中的十进制数。@JLRishe我很确定这两个都不是原始的。谢谢。我认为这个链接也值得注意:@BobHorn补充道。谢谢