C# NUnit TestCaseSource Passing Parameter

前端 未结 3 1714
予麋鹿
予麋鹿 2021-02-04 06:58

I have the following method which generates a set of test cases!

public IEnumerable PrepareTestCases(param1)
{
    foreach (string e         


        
3条回答
  •  無奈伤痛
    2021-02-04 07:16

    In my case I would like to load data from a CSV file but I couldn't pass the filename to the "datasource". After struggling a bit around I come to this two cent solution.

    At first I inherited TestCaseSourceAttirbute

    /// 
    /// FactoryAttribute indicates the source to be used to provide test cases for a test method.
    /// 
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
    public class TestCaseCsvAttribute : TestCaseSourceAttribute 
    {
        public TestCaseCsvAttribute(Type mapped, Type config) : base(typeof(TestCsvReader<,>).MakeGenericType(mapped, config), "Data")
        { }
    }
    

    then I created the data layer, in my case a CSV reader.

        /// 
        /// Test data provider
        /// 
        /// Type to return in enumerable
        /// Configuration type that provide Filenames
        public sealed class TestCsvReader
        {
            /// 
            /// Initializes a new instance of the  class.
            /// 
            public TestCsvReader()
            {
                this.Config = (C)Activator.CreateInstance();
            }
    
            /// 
            /// Gets or sets the configuration.
            /// 
            /// 
            /// The configuration.
            /// 
            private C Config { get; set; }
    
            /// 
            /// Gets the filename.
            /// 
            /// 
            /// The filename.
            /// 
            /// 
            /// 
            private string Filename
            {
                get
                {
                    try
                    {
                        string result = Convert.ToString(typeof(C).GetProperty(string.Format("{0}Filename", typeof(T).Name)).GetValue(this.Config));
                        if (!File.Exists(result))
                            throw new Exception(string.Format("Unable to find file '{0}' specified in property '{1}Filename' in class '{1}'", result, typeof(C).Name));
    
                        return result;
                    }
                    catch
                    {
                        throw new Exception(string.Format("Unable to find property '{0}Filename' in class '{1}'", typeof(T).Name, typeof(C).Name));
                    }
                }
            }
    
            /// 
            /// Yields values from source
            /// 
            /// 
            public IEnumerable Data()
            {
                string file = this.Filename;
    
                T[] result = null;
                using (StreamReader reader = File.OpenText(file))
                {
                    //TODO: do it here your magic
                }
                yield return new TestCaseData(result);
            }
    }
    

    Then I created a class with the only scope to contain properties with the file paths. There's a name convention about the property, that's ClassTypeName + "Filename".

    public class Configurations
    {
        public string ConflictDataFilename
        {
            get
            {
                return @"C:\test.csv";
            }
        }
    }
    

    At this point just decorate accordingly the test, with the type of class to map to data and the class that contain file path.

    [Test(Description="Try this one")]
    [TestCaseCsv(typeof(ClassMappedToData), typeof(Configurations))]
    public void Infinite(ClassMappedToData[] data)
    {
    }
    

    Hope this can help a bit.

提交回复
热议问题