草庐IT

c# - 您可以在单元测试项目中使用 Visual Studio 数据库项目来为功能测试设置一个空数据库吗?

coder 2024-05-27 原文

多年来,我们一直使用以下代码在基类中为 DAL 的功能测试设置数据库,这对我们来说效果非常好。

/// <summary>
/// Initializes the test class by creating the integration database.
/// </summary>
[TestInitialize]
public virtual void TestInitialize()
{
    DataContext = new DataContext(ConnectionString);

    CleanupPreviousTestRunDatabases();

    if (DataContext.Database.Exists())
    {
        DataContext.Database.Delete();
    }

    DataContext.Database.Create();
    DataContext.Database.ExecuteSqlCommand(String.Format(Strings.CreateLoginCommand, DatabaseUserName, DatabasePassword));
    DataContext.Database.ExecuteSqlCommand(String.Format("CREATE USER {0} FOR LOGIN {0}", DatabaseUserName));
    DataContext.Database.ExecuteSqlCommand(String.Format("EXEC sp_addrolemember 'db_owner', '{0}'", DatabaseUserName));
}

但是,使用 Entity Framework 不会设置数据库的所有组件,我们希望找出我们的 EF DAL 模型与实际数据库之间的差异。

我们将 SSDT 工具/Visual Studio 数据库项目用于我们所有的数据库工作,我知道您可以编写 SQL 单元测试,并且在这些 SQL 单元测试中,我看到了设置和创建基于数据库项目本身。这是我想做的,但来 self 们的其他功能测试库。

我可以引用这些库并编写一些设置代码,但我正在寻找的是:

a) 如何提供用于部署的数据库项目?

b) 如何在代码中而不是在 app.config 中指定连接字符串,例如使用 localdb 而不是动态命名的数据库?

namespace Product.Data.Tests
{
    using Microsoft.Data.Tools.Schema.Sql.UnitTesting;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class FunctionalTest
    {
        [TestInitialize]
        public virtual void TestInitialize()
        {
            SqlDatabaseTestClass.TestService.DeployDatabaseProject();
            SqlDatabaseTestClass.TestService.GenerateData();
        }
    }
}

SQL 单元测试项目中的 app.config 不包含对用于创建它的原始数据库项目的任何引用,并且反编译一些测试代码并查看它是如何工作的,我没有看到任何迹象.是否假设解决方案中只有一个数据库项目?

最佳答案

根据@Ed Elliott 发布的链接的一些指导,我能够做到这一点。您需要添加 Microsoft.SqlServer.Dac 作为来自 C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC 的程序集引用\120\Microsoft.SqlServer.Dac.dll(Visual Studio 2015)。它是 SSDT 工具的一部分,因此我确信早期版本的路径可能不同。

[TestClass]
public class DatabaseTest
{
    protected string DatabaseConnectionString = $@"Data Source=(localdb)\v11.0; Integrated Security=True";
    protected DatabaseContext DatabaseContext;
    protected string DatabaseName = $"UnitTestDB_{Guid.NewGuid().ToString("N").ToUpper()}";

    public TestContext TestContext { get; set; }

    [TestInitialize]
    public virtual void TestInitialize()
    {
        var instance = new DacServices(DatabaseConnectionString);
        var path     = Path.GetFullPath(Path.Combine(TestContext.TestDir, 
                                        @"..\..\..\Build\Database\Database.dacpac"));

        using (var dacpac = DacPackage.Load(path))
        {
            instance.Deploy(dacpac, DatabaseName);
        }

        DatabaseContext = new DatabaseContext(DatabaseConnectionString);
    }

    [TestCleanup]
    public virtual void TestCleanup()
    {
        DeleteDatabase(DatabaseName);
    }
}

然后如何将其用于单元测试项目中的功能测试。

[TestClass]
public class CustomerTypeTests : DatabaseTest
{
    private CustomerType customerType;

    [TestInitialize]
    public override void TestInitialize()
    {
        base.TestInitialize();

        customerType = new CustomerType
                       {
                           Name = "Customer Type"
                       };
    }

    [TestMethod]
    public void AddOrUpdateCustomerType_ThrowExceptionIfNameIsNull()
    {
        ExceptionAssert.Throws<ArgumentNullException>(() => DatabaseContext.AddOrUpdateCustomerType(customerType));
    }
}

请注意,您还应该设置Build Dependencies,以便您的单元测试项目依赖于数据库项目,确保首先构建它并生成正确的dacpac 文件。

这为我们解决的问题是,这是否为我们提供了一个真正的数据库,而不是仅基于 Entity Framework 模型的数据库,它缺少相当多的 SQL 结构(可以预期),尤其是默认约束、索引和其他重要元素的一个数据库。在我们的 DAL 层,这对我们来说至关重要。

关于c# - 您可以在单元测试项目中使用 Visual Studio 数据库项目来为功能测试设置一个空数据库吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37199830/

有关c# - 您可以在单元测试项目中使用 Visual Studio 数据库项目来为功能测试设置一个空数据库吗?的更多相关文章

  1. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  2. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  3. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  4. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  6. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  7. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  8. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  9. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  10. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

随机推荐