Xunit 2.3.0无法将日期作为内联参数传递

时间:2017-12-15 08:25:25

标签: xunit xunit.net

在xUnit 2.2和之前的版本中,我们能够在实现Theory时将日期字符串作为内联数据传递。

        [Theory]
        [InlineData("title 1", "testing 1", 1, "Educational", "2017-3-1", "2018-12-31")]
        [InlineData("title 2", "testing 2", 2, "Self Employment", "2017-2-1", "2018-2-28")]
        public async Task WhenPassingCorrectData_SuccessfullyCreate(string title, string description, int categoryId, string category, DateTime startDate, DateTime endDate)
        {

        }

但是对于2.3更新,这似乎被打破了,Visual Studio正在给出编译错误。

  

该值不能转换为方法参数'startDate'   输入'System.DateTime

有没有人为这个其他人解决了必须接收日期为字符串并将其转换为测试方法的内容?

这是否是这个版本中的临时错误,将在未来版本中修复?

PS:我在VS2017上的.netcore项目中使用xUnit

4 个答案:

答案 0 :(得分:13)

您可以使用MemberDataAttribute明确说明: -

static object[][] CorrectData
{
    new object[] { "title 1", "testing 1", 1, "Educational", new DateTime(2017,3,1), new DateTime(2018,12,31))],
    new object[] { "title 2", "testing 2", 2, "Self Employment", new DateTime(2017, 2, 1), new DateTime(2018, 2, 28)}
}

[Theory, MemberData(nameof(CorrectData))]
public async Task WhenPassingCorrectData_SuccessfullyCreate(string title, string description, int categoryId, string category, DateTime startDate, DateTime endDate)
{

}

(你也可以让属性返回IEnumerable<object[]>,你通常使用yield return enumerator syntax,但我相信上面是C#目前提供的最清晰的语法<) / p>

答案 1 :(得分:3)

目前最好的方法是使用TheoryData,以便可以使用强类型输入。 Creating strongly typed xUnit theory test data with TheoryData

TheoryData<DateTime> MemberData = new TheoryData<DateTime>
{
 DateTime.Now, 
 new DateTime(), 
 DateTime.Max
}

答案 2 :(得分:1)

这是将强类型的测试数据传递到xUnit Tests中的好方法

Blog Post

Source Code

public class SampleData
{
    public int A { get; set; }
    public int B { get; set; }
    public int C => A + B;
}

public class UnitTest1
{
    /// <summary>
    /// The test data must have this return type and should be static
    /// </summary>
    public static IEnumerable<object[]> TestData
    {
        get
        {
            //Load the sample data from some source like JSON or CSV here.
            var sampleDataList = new List<SampleData>
            {
                new SampleData { A = 1, B = 2 },
                new SampleData { A = 3, B = 2 },
                new SampleData { A = 2, B = 2 },
                new SampleData { A = 3, B = 23 },
                new SampleData { A = 43, B = 2 },
                new SampleData { A = 3, B = 22 },
                new SampleData { A = 8, B = 2 },
                new SampleData { A = 7, B = 25 },
                new SampleData { A = 6, B = 27 },
                new SampleData { A = 5, B = 2 }
         };

            var retVal = new List<object[]>();
            foreach(var sampleData in sampleDataList)
            {
                //Add the strongly typed data to an array of objects with one element. This is what xUnit expects.
                retVal.Add(new object[] { sampleData });
            }
            return retVal;
        }
    }

/* Alternate form

    public static IEnumerable<object[]> TestData() 
    {
        yield return new [] { new SampleData { A = 1, B = 2 } };
        yield return new [] { new SampleData { A = 3, B = 2 } };
        yield return new [] { new SampleData { A = 2, B = 2 } };
        yield return new [] { new SampleData { A = 3, B = 23 } };
        yield return new [] { new SampleData { A = 43, B = 2 } };
        yield return new [] { new SampleData { A = 3, B = 22 } };
        yield return new [] { new SampleData { A = 8, B = 2 } };
        yield return new [] { new SampleData { A = 7, B = 25 } };
        yield return new [] { new SampleData { A = 6, B = 27 } };
        yield return new [] { new SampleData { A = 5, B = 2 } };
    }
*/

/* Or:

    public static IEnumerable<object[]> TestData() =>
        from x in new[] { 
            new SampleData { A = 1, B = 2 },
            new SampleData { A = 3, B = 2 },
            new SampleData { A = 2, B = 2 },
            new SampleData { A = 3, B = 23 },
            new SampleData { A = 43, B = 2 },
            new SampleData { A = 3, B = 22 },
            new SampleData { A = 8, B = 2 },
            new SampleData { A = 7, B = 25 },
            new SampleData { A = 6, B = 27 },
            new SampleData { A = 5, B = 2 } }
        select new object[] { x};
    */

    /// <summary>
    /// Specify the test data property with an attribute. This method will get executed 
    /// for each SampleData object in the list
    /// </summary>
    [Theory, MemberData(nameof(TestData))]       
    public void Test1(SampleData sampleData)
    {
        Assert.Equal(sampleData.A + sampleData.B, sampleData.C);
    }
}

答案 3 :(得分:1)

似乎此错误已在v2.4.0 +中修复(此功能至少在v2.3.1中停止了工作?)

如果无法通过修复将xunit升级到某个版本,则可能等效于xunit隐式执行的操作:

https://github.com/xunit/xunit/blob/main/src/xunit.v3.core/Sdk/Reflection/Reflector.cs#L63-L69

[Theory]
[InlineData("title 1", "testing 1", 1, "Educational", "2017-3-1", "2018-12-31")]
[InlineData("title 2", "testing 2", 2, "Self Employment", "2017-2-1", "2018-2-28")]
public async Task WhenPassingCorrectData_SuccessfullyCreate(
    string title,
    string description,
    int categoryId,
    string category,
    string startDate, // <-- change from `DateTime` to `string`
    string endDate)   // <-- change from `DateTime` to `string`
{
    var expectedStartDate = DateTime.Parse(startDate); // <-- add this
    var expectedEndDate = DateTime.Parse(endDate);     // <-- add this

    //  rest of test ...

}

否则,如果测试更加复杂,则可以像其他人建议的那样使用MemberDataAttribute