多年来,我们使用以下代码在基类中为我们的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单元测试中,我已经看到了基于的设置和创建数据库的能力。数据库项目本身。这是我想要做的,但是来自我们的其他功能测试库。
我可以参考这些库并编写一些设置代码,但我正在寻找的是:
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不包含对用于创建它的原始数据库项目的任何引用,并且反编译一些测试代码并查看它是如何工作的,我不会&#39;看到任何迹象。是否假设解决方案中只有一个数据库项目?
答案 0 :(得分:8)
根据@Ed Elliott发布的链接的指示,我能够实现这一目标。您需要从Microsoft.SqlServer.Dac
(Visual Studio 2015)添加C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\120\Microsoft.SqlServer.Dac.dll
作为程序集引用。它是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
文件。
这为我们解决的是,这给了我们一个真正的数据库,而不仅仅是基于实体框架的模型,它缺少相当多的SQL结构(预期),特别是默认约束,索引和其他重要元素一个数据库。在我们的DAL层,这对我们来说至关重要。
答案 1 :(得分:5)
我认为你所拥有的过程有点过于复杂(如果我理解正确,我可能没有!)。
我在ssdt中进行单元测试的目的是:
要部署项目,有几种方法,您可以:
一旦部署完成运行测试,从代码或脚本中发布dacpac(项目)非常简单,你可以:
如果您自己控制发布,那么当您使用它时,它会为您提供更多控制 plus ,您正在测试将在其他环境中使用的相同部署系统(假设您使用dacpac&# 39;要部署)。
编