SQL Server 2012 - SP、SSDTユニットテスト、ネストトランザクションの問題
-
21-12-2019 - |
質問
VS 2013のSSDTが90%のシナリオでうまく機能しているが、ストアドプロシージャがロールバックトランザクションのテストされている場合に失敗した状況を持っています。
SQL Serverは、ネストされたトランザクションが本当にネストされていないため、内部トランザクションをロールバックします。通常、これは問題ではありませんが、SSDTユニットテストのコンテキスト内では、TransactionScope
/ Rollbackで単体テスト方法を折り返すことで、わずかにカスタマイズされたアプローチを取っています。これは問題を引き起こすものであり、単体テストデータのクレンジング後のテストに関連する問題を解決しながら
ロールバックを必要とする私たちの手順で条件が発生したときにこれを回避するために、手順の終わりの直前にBEGIN TRANSACTION
を追加します。これはトランザクション数のバランスをとります。プロシージャの前後にPRESS PROCESS EXECを確認するために、その最後の開始の暗黙のコミットが完了したことを確認しました。
質問は:通常の操作の下で(つまり、呼び出し側のミドルウェアのTransactionScope
に囲まれていません)、同じバッチ内のストアドプロシージャEXECに続くステートメントの問題を開くように見えます。 。 EFなどのORMやADO.NETと直接ストアドプロシージャを呼び出すときの問題はありますか?確かに、ステートメントのバッチは開かれたトランザクションの暗黙の完成を終了することができますか?
例えば/参照ストアドプロシージャには、次のようなものが含まれます。
CREATE PROCEDURE [dbo].[ProcName]
/* params */
AS
SET NOCOUNT ON
SET XACT_ABORT ON
/* set var according to transcount check*/
DECLARE @IsInsideTransaction BIT = CASE WHEN @@trancount > 0 THEN 1 ELSE 0 END
/* apply new information to data store */
begin TRANSACTION
declare @RetVal int = 0
begin try
insert into dbo.AMessageTable
(/* some columns */)
values
(/* some values */)
set @messageId = scope_identity()
commit transaction
set @retVal = @messageId
end try
begin catch
SELECT ERROR_NUMBER() AS ErrorNumber, ERROR_MESSAGE() AS ErrorMessage;
SET @RetVal = -1;
ROLLBACK TRANSACTION
/* ### this gets us out of the transaction count issue within the UT ### */
IF @IsInsideTransaction = 1
BEGIN
BEGIN TRANSACTION
END
end catch
return @retVal
GO
.
そして私達はこのようなものを含むように自動生成されたSSDTユニットテストコードを変更します:
[TestInitialize()]
public void TestInitialize() {
_transaction = new TransactionScope(TransactionScopeOption.RequiresNew);
base.InitializeTest();
}
[TestCleanup()]
public void TestCleanup() {
base.CleanupTest();
if (_transaction != null) {
_transaction.Dispose();
}
}
. 解決
あなたはあなたに2つの問題があると思われます。
最初のものは、あなたがあなたのプロダクションコードであなたのテスト作業をするためにコードでミキシングしていることです。これは一般に、プロダクションでテストコードを実行する必要があるか、またはデプロイするときにストアドプロシージャを変更する必要があることを意味するため、一般的には悪い慣習と見られます。
2番目は、あなたのテストが確実に機能するようになること、そしてあなたは奇妙な取引の組み合わせを作成し、それがかなり多くの複雑さを追加しています。
TSQLTを見てきましたが、特に偽のテーブルを作成し、テストデータを挿入してからストアドプロシージャを呼び出します。TSQLTは、変更前の同じ状態でデータベースを終えたことを確認しますが、偽のテーブルを正しく使用する場合は、テストの前後にある状態になっています。