如何测试C#代码和Sql Server存储过程之间的同步

如何测试C#代码和Sql Server存储过程之间的同步,c#,sql-server,testing,stored-procedures,C#,Sql Server,Testing,Stored Procedures,为了在SQL Server和C#之间进行交互,我使用了对象、参数和存储过程 我的问题是,在执行之前,我不知道它是否仍然与数据库同步 例如,如果我有以下存储过程: create procedure psSync ( @Argument VARCHAR(50) ) --do stuff 我的代码中将包含: String myArgument="20131110" SqlCommand sqlcmd = new SqlCommand { CommandType = CommandType.S

为了在SQL Server和C#之间进行交互,我使用了对象、参数和存储过程

我的问题是,在执行之前,我不知道它是否仍然与数据库同步

例如,如果我有以下存储过程:

create procedure psSync
(
    @Argument VARCHAR(50)
)
--do stuff
我的代码中将包含:

String myArgument="20131110"
SqlCommand sqlcmd = new SqlCommand { CommandType = CommandType.StoredProcedure, CommandText = "psSync"};
sqlCommand.Parameters.AddWithValue("@Argument", myArgument);
//execute sql command
这里一切都很好

但是如果我把我的进程改为

create procedure psSync
(
    --Desync!
    @Argument Datetime
)
--do stuff
忘了把我的参数改为datetime,它会崩溃,我经常会注意到这个错误,太晚了

我首先尝试运行单元测试,在开发数据库中使用begin transaction和rollback执行存储过程,但我不喜欢这样:

  • 这需要很长时间
  • 它可能在prod中错误运行
  • 它将数据库配置存储在测试dll中
所以我的问题是:


如何快速、高效、安全地测试C代码和SqlServer代码(SqlCommand->Storage Procedure)之间的所有sql链接?

只是好奇,为什么要添加这种模式验证? 更改过程参数不是这样发生的,对吧。任何正在修改的人都必须知道,这也需要更改代码

SELECT  OBJECT_NAME(ssp.object_id) objectName
        ,ssp.name ParameterName
        ,sst.name ParameterDataType
        ,ssp.max_length
        ,ssp.precision
        ,ssp.scale
FROM sys.parameters  ssp
JOIN sys.types sst
    ON ssp.system_type_id=sst.system_type_id
WHERE OBJECT_NAME(ssp.object_id) = 'pr_test1'
但是,如果您遇到这种情况并且确实需要这样做,您必须在实际调用数据库过程之前,提出自己的框架或API集,您可以从C#代码中调用这些框架或API集。到目前为止,我还没有见过这种类型的验证,因为它会增加很多开销,这取决于它是针对一个或两个过程实现的还是跨所有DB调用实现的

您可以编写SQL API,它将返回DB all/selected过程以及当前的模式定义。检查此查询。sys.parameters表中还有其他有用的信息

SELECT  OBJECT_NAME(ssp.object_id) objectName
        ,ssp.name ParameterName
        ,sst.name ParameterDataType
        ,ssp.max_length
        ,ssp.precision
        ,ssp.scale
FROM sys.parameters  ssp
JOIN sys.types sst
    ON ssp.system_type_id=sst.system_type_id
WHERE OBJECT_NAME(ssp.object_id) = 'pr_test1'
示例结果如下所示

但请记住,如果您没有提供正确的频率或何时获取此信息,异步问题仍然可能发生。您所能做的最好的事情就是在对象调用之前获取这些信息。你知道一直这样做的开销是多少


与环境的交互,如:DB、服务等,是功能和集成测试的工作。这些测试是缓慢的,它们的数量应该是最小的

如果单元测试需要很长时间,那么它不是单元测试。 单元测试可能会检查预期参数是否设置为SqlCommand并调用了execute方法。应该模拟数据库上下文


该单元测试的更正由更新存储过程的人员负责。或者应该有一些DB规范,单元测试应该与之同步。

这就是ORM被发明的原因之一。NHibernate或实体框架或其他。感谢您的帮助。我想进行模式验证,因为您永远不知道过程是用于C代码还是仅用于Db使用=>存储过程修改并不总是意味着C代码修改。我理解这个问题似乎显示出缺乏严谨性,但在我看来,这与驱动单元测试创建的逻辑是相同的。一旦我为这个测试实现了一个正确的框架,我就会回到这个线程。