Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 使用自动配置的localdb进行单元测试;我怎么清理?_.net_Sql Server_Localdb - Fatal编程技术网

.net 使用自动配置的localdb进行单元测试;我怎么清理?

.net 使用自动配置的localdb进行单元测试;我怎么清理?,.net,sql-server,localdb,.net,Sql Server,Localdb,我已经配置了一个.mdf文件和一个localdb连接字符串,以便在单元测试中使用,如下所示: <connectionStrings> <add name="TestData" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0; AttachDBFilename='|DataDirectory|\TestData.mdf'; Integrated S

我已经配置了一个.mdf文件和一个localdb连接字符串,以便在单元测试中使用,如下所示:

<connectionStrings>
        <add name="TestData" providerName="System.Data.SqlClient" connectionString="Data Source=(localdb)\v11.0; AttachDBFilename='|DataDirectory|\TestData.mdf'; Integrated Security=True"/>
</connectionStrings>
一旦我为测试正确配置了部署文件,这将非常有效:将.mdf的副本附加到LocalDB的默认实例,并且SqlClient连接到该实例而无需任何配置。它只是工作

但是我以后怎么收拾呢?在我的本地机器上,我可以定期使用SSM手动分离旧的测试数据库,但在CI服务器上,显然最好让单元测试自行清理


是否有类似的自动逻辑方法使localdb数据库与实例分离?

我就是这样删除localdb数据库的。我不喜欢的是.mdf也被删除了。我首先将其复制到tem目录并使用该副本创建db,从而克服了这一问题

var sc = new Microsoft.SqlServer.Management.Common.ServerConnection(your localDB SqlConnection here);
var server = new Microsoft.SqlServer.Management.Smo.Server(sc);
server.KillDatabase(dbName here);
希望这有帮助 菲尔像这样:

 // ProjectPath/bin/Debug/dbfile.mdf

 [TestInitialize]
 public void SetUp()
 {           
    AppDomain.CurrentDomain.SetData(
      "DataDirectory", Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""));
  }

如果您谈论的是单元测试,比如xUnit,那么您可以向测试本身添加一些属性,以便对任何涉及数据库的测试进行回滚

实际上,它在企业级事务中运行测试。这使得每个测试的数据都保持稳定,并且不需要模拟数据库;它可以有效地成为验收测试

例如,在xUnit中:

[事实] [自动回滚] public void应插入有效数据 { //排列:假设有一个对象sut支持insert, //你有一些数据 //行为: int key=sut.Insertdata; //断言: Assert.Truekey>0,应返回主键; 插入的var=sut.Getkey; Assert.Equaldata,inserted,CompareAllButKey; } 仅供参考:sut是测试中的情况或测试中的受试者

在上查看这篇文章可能会有所帮助。在那篇文章的结尾还有其他一些不错的链接


顺便说一句,我使用了xUnit作为示例,但其他测试框架在控制回滚方面也有类似的属性。

是的,但您可能不需要它

我目前正在使用一个过程,即按照wbx911/Tim Post在其答案中的方式连接数据库。但是,如果要附加原始数据库的副本(例如,由项目/解决方案构建创建的副本),则不需要断开连接。如果没有连接到数据库,它将在下一次测试运行时被覆盖

如果连接了大量数据库副本,或者只是不想清理连接的所有内容,那么可以使用以下存储过程,连接到localDb实例的主数据库,这是我个人使用的一个示例:

CREATE PROCEDURE [dbo].[DettachTestDatabases]
AS

BEGIN
DECLARE  @imax INT, 
         @i    INT 
DECLARE  @Name VARCHAR(255)

DECLARE  @DbsToDrop TABLE(RowID INT IDENTITY ( 1 , 1 ), 
                          name VARCHAR(255)
                         ) 

INSERT @DbsToDrop
SELECT [name]
  FROM [master].[sys].[databases]
  WHERE 
    --Remove all local dbs with *SomeText*.mdf or SomeOtherTextin name
    (name like '%SomeText%.mdf' or name like '%SomeOtherText%')
    -- Exclude VS test dbs (add more as required...)
    and (name not like '%TESTS.%');

SET @imax = @@ROWCOUNT 
SET @i = 1 

WHILE (@i <= @imax) 
  BEGIN 
        SELECT @Name = name 
        FROM   @DbsToDrop 
        WHERE  RowID = @i

        EXEC master.dbo.sp_detach_db @dbname = @Name;

        PRINT 'Dettatched ' + @Name;

        SET @i = @i + 1;
  END   --while

END --sp
GO
我使用一个命名约定来确定要删除哪些dbs,因此使用类似的语句。VisualStudio附加了两个db,或者至少我认为它们属于VS,用于管理测试结果,我不想分离这些db,因此不喜欢这种情况。这里有一个master.dbo.sp_detach_db,它按名称进行跟踪,因此您实际上只需要引用名称,但由于localdb名称可能有点疯狂,因此查找将非常有用

在测试结束时,我还没有实现自动化,因为我觉得没有必要这样做,因为覆盖工作正常,但我可以随时在SSMS中执行它。但是,如果您觉得有必要,您只需要管理清理代码对SP的调用

连接dbs的过程有些昂贵。我选择了cleanup方法/SP,它删除所有变量数据并重新设定表的种子,以使数据库处于一致状态,这非常快,而不是重新连接数据库


如果你发现有什么改进的地方,我真的很想知道

您正在使用的单元测试框架是否允许您在MS测试、NUnit 3和XUnit中附加清理方法?如果是这样的话,您可以连接下面这样的东西,以便在测试结束时自动分离数据库

public static void CleanUp()
{
    using (var connection = new SqlConnection(ConnectionString))
    {
        connection.Open();

        using (var command = connection.CreateCommand())
        {
            var sql = "DECLARE @dbName NVARCHAR(260) = QUOTENAME(DB_NAME());\n" +
                "EXEC('exec sp_detach_db ' + @dbName + ';');";
            command.CommandText = sql;
            command.ExecuteNonQuery();
         }
    }
}

为什么不模拟您的依赖关系并创建一个真正的单元测试呢?“就目前情况而言,您所做的是一个集成测试。”丹尼尔曼承认这是正确的,但可以接受的是,它非常接近。我只是没有时间为db构建一个真正的模拟。有人提出了一个解决方案吗?我想使用localdb进行集成测试,但事实证明,基于localdb可以附加一个DB而不是分离它的愚蠢方式,这是非常困难的。在不进行大量时间投资的情况下,使用某些技术(如Entity Framework)进行模拟的价值是有限的。不,这很好。我将.mdf设置为部署文件,因此每次测试都会将其复制为新文件,因此删除mdf是可以的。我试试看。@BenCollins帮你做的?当数据库名是自动的时,如何获取它?@SimonHartcher No。获取生成的数据库名对我来说也是一个阻塞问题。从那以后,我或多或少地放弃了整个机制,转而使用正确模拟的存储库接口,以避免对运行的依赖
ning DB。@BenCollins我发现可以从SqlConnection中获取数据库名称,但这对我来说并不管用。我想使用repository模式,但由于一些原因我无法使用。这并不能以任何方式回答这个问题。