简体   繁体   English

针对 SQL 服务器数据运行 XUnit 测试时出错 - 为 Tests.UnitTest1.Test1 上的 Tests.SqlServerDataAttribute 指定的数据发现器不存在

[英]Error running XUnit Test against SQL Server Data - Data discoverer specified for Tests.SqlServerDataAttribute on Tests.UnitTest1.Test1 does not exist

I have an issue running some integration tests with xunit.我在使用 xunit 运行一些集成测试时遇到问题。 I have a process that inserts data to a MSSQL Database, then I want to run some tests over this data.我有一个将数据插入 MSSQL 数据库的进程,然后我想对该数据运行一些测试。

I am using.Net Core and xunit for the tests, and have used the sample from herehttps://github.com/xunit/samples.xunit/tree/main/SqlDataExample to create these.我正在使用 .Net Core 和 xunit 进行测试,并使用此处https://github.com/xunit/samples.xunit/tree/main/SqlDataExample中的示例来创建这些。

The error I am getting is Data discoverer specified for Tests.SqlServerDataAttribute on Tests.UnitTest1.Test1 does not exist.我收到的错误是为 Tests.UnitTest1.Test1 上的 Tests.SqlServerDataAttribute 指定的数据发现器不存在。

Relevant code snippets below:相关代码片段如下:

        [SqlServerData("ServerIp", "DbName", "DbUser","DbPwd", "SELECT name FROM Users")]
        public void Test1(string name)
        {
            Assert.Equal("T C One", name);
            
        }
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Text;

namespace Tests
{
    /// <summary>
    /// Provides a data source for a data theory, with the data coming a Microsoft SQL Server.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
    [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "The values are available indirectly on the base class.")]
    [SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes", Justification = "This attribute is designed as an extensibility point.")]
    public class SqlServerDataAttribute : OleDbDataAttribute
    {
        const string sqlWithTrust =
            "Provider=SQLOLEDB; Data Source={0}; Initial Catalog={1}; Integrated Security=SSPI;";

        const string sqlWithUser =
            "Provider=SQLOLEDB; Data Source={0}; Initial Catalog={1}; User ID={2}; Password={3};";


        /// <summary>
        /// Creates a new instance of <see cref="SqlServerDataAttribute"/>, using a trusted connection.
        /// </summary>
        /// <param name="serverName">The server name of the Microsoft SQL Server</param>
        /// <param name="databaseName">The database name</param>
        /// <param name="selectStatement">The SQL SELECT statement to return the data for the data theory</param>
        public SqlServerDataAttribute(string serverName,
            string databaseName,
            string selectStatement)
            : base(String.Format(CultureInfo.InvariantCulture, sqlWithTrust, serverName, databaseName), selectStatement)
        {
        }

        /// <summary>
        /// Creates a new instance of <see cref="SqlServerDataAttribute"/>, using the provided username and password.
        /// </summary>
        /// <param name="serverName">The server name of the Microsoft SQL Server</param>
        /// <param name="databaseName">The database name</param>
        /// <param name="userName">The username for the server</param>
        /// <param name="password">The password for the server</param>
        /// <param name="selectStatement">The SQL SELECT statement to return the data for the data theory</param>
        public SqlServerDataAttribute(string serverName,
                                      string databaseName,
                                      string userName,
                                      string password,
                                      string selectStatement)
            : base(String.Format(CultureInfo.InvariantCulture, sqlWithUser, serverName, databaseName, userName, password),
                   selectStatement)
        { }
    }
}

using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using Xunit.Sdk;

namespace Tests
{
    /// <summary>
    /// Represents an implementation of <see cref="DataAttribute"/> which uses an
    /// instance of <see cref="IDataAdapter"/> to get the data for a <see cref="TheoryAttribute"/>
    /// decorated test method.
    /// </summary>
    [DataDiscoverer("DataAdapterDataAttributeDiscoverer", "Tests")]
    public abstract class DataAdapterDataAttribute : DataAttribute
    {
        /// <summary>
        /// Gets the data adapter to be used to retrieve the test data.
        /// </summary>
        protected abstract IDataAdapter DataAdapter { get; }

        /// <summary>
        /// Returns <c>true</c> if the data attribute wants to enumerate data during discovery. By
        /// default, this attribute assumes that data enumeration is too expensive to do during
        /// discovery, and therefore defaults to <c>false</c>.
        /// </summary>
        public bool EnableDiscoveryEnumeration { get; set; }

        /// <inheritdoc/>
        public override IEnumerable<object[]> GetData(MethodInfo methodUnderTest)
        {
            DataSet dataSet = new DataSet();
            IDataAdapter adapter = DataAdapter;

            try
            {
                adapter.Fill(dataSet);

                foreach (DataRow row in dataSet.Tables[0].Rows)
                    yield return ConvertParameters(row.ItemArray);
            }
            finally
            {
                IDisposable disposable = adapter as IDisposable;
                if (disposable != null)
                    disposable.Dispose();
            }
        }

        object[] ConvertParameters(object[] values)
        {
            object[] result = new object[values.Length];

            for (int idx = 0; idx < values.Length; idx++)
                result[idx] = ConvertParameter(values[idx]);

            return result;
        }

        /// <summary>
        /// Converts a parameter to its destination parameter type, if necessary.
        /// </summary>
        /// <param name="parameter">The parameter value</param>
        /// <returns>The converted parameter value</returns>
        protected virtual object ConvertParameter(object parameter)
        {
            if (parameter is DBNull)
                return null;

            return parameter;
        }
    }
}
using Xunit.Abstractions;
using Xunit.Sdk;

namespace Tests
{
    public class DataAdapterDataAttributeDiscoverer : DataDiscoverer
    {
        public override bool SupportsDiscoveryEnumeration(IAttributeInfo dataAttribute, IMethodInfo testMethod)
            => dataAttribute.GetNamedArgument<bool>("EnableDiscoveryEnumeration");
    }
}

I have verified the connection string and the query against the database, and I have run SQL Profiler on the database when attempting to run the test but nothing is hitting the database.我已经验证了连接字符串和对数据库的查询,并且在尝试运行测试时在数据库上运行了 SQL Profiler,但没有任何数据命中数据库。

Any idea what I am missing?知道我错过了什么吗?

I managed to find the issue.我设法找到了问题所在。 You need a fully qualified type name on the DataDiscoverer:您需要 DataDiscoverer 上的完全限定类型名称:

[DataDiscoverer("Tests.DataAdapterDataAttributeDiscoverer", "Tests")]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM