このままテストを繰り返すとデータが溜まっていってテスト整合性保てなくなる場合があることや、テスト用のDBはコンテナで使い捨てにすることを踏まえ、前処理後処理をいれる。
前処理はこんな感じにしておく。DBが存在したら、どういう使われ方したかわからんからDropしてからDBを作成。そのあと、テスト用のテーブル作成。
[TestInitialize]
public void Setup()
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// データベースが存在するか確認し、存在する場合は削除
string checkDbExistenceQuery = $"SELECT database_id FROM sys.databases WHERE Name = '{testDatabase}'";
using (var command = new SqlCommand(checkDbExistenceQuery, connection))
{
var databaseId = command.ExecuteScalar();
if (databaseId != null)
{
string dropDbQuery = $"DROP DATABASE {testDatabase}";
using (var dropCommand = new SqlCommand(dropDbQuery, connection))
{
dropCommand.ExecuteNonQuery();
}
}
}
// テスト用データベースの作成
string createDbQuery = $"CREATE DATABASE {testDatabase}";
using (var command = new SqlCommand(createDbQuery, connection))
{
command.ExecuteNonQuery();
}
// テスト用テーブルの作成
string useDbQuery = $"USE {testDatabase}";
string createTableQuery = "CREATE TABLE TestTable (date DATETIME NOT NULL, num INT NOT NULL)";
using (var command = new SqlCommand($"{useDbQuery}; {createTableQuery}", connection))
{
command.ExecuteNonQuery();
}
}
}
後処理でも、使ったDBを削除するお片付け処理を入れとく
[TestCleanup]
public void Cleanup()
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// テスト用データベースの削除
string dropDbQuery = $"DROP DATABASE {testDatabase}";
using (var command = new SqlCommand(dropDbQuery, connection))
{
command.ExecuteNonQuery();
}
}
}
DB消えた
DB作成された
テーブル作成された。
もちろん、データなし。
string alterDbQuery = $"ALTER DATABASE {testDatabase} SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
using (var alterCommand = new SqlCommand(alterDbQuery, connection))
{
alterCommand.ExecuteNonQuery();
}
これでとりあえず、テストを何回繰り返してもエラーにならなくなった
今時点で、最終的なテストプログラムは以下
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Data.SqlClient;
using SqlServerOperation;
namespace DatabaseOperationTests
{
[TestClass]
public class DataInserterTests
{
private readonly string server = "192.168.10.13";
private readonly string username = "sa";
private readonly string password = "P@$$w0rd";
private readonly string testDatabase = "TestDB";
private readonly string connectionString;
public DataInserterTests()
{
connectionString = $"Server={server};Database=master;User Id={username};Password={password};";
}
[TestInitialize]
public void Setup()
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// データベースが存在するか確認し、存在する場合は削除
string checkDbExistenceQuery = $"SELECT database_id FROM sys.databases WHERE Name = '{testDatabase}'";
using (var command = new SqlCommand(checkDbExistenceQuery, connection))
{
var databaseId = command.ExecuteScalar();
if (databaseId != null)
{
// データベースへのすべての接続を切断
string alterDbQuery = $"ALTER DATABASE {testDatabase} SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
using (var alterCommand = new SqlCommand(alterDbQuery, connection))
{
alterCommand.ExecuteNonQuery();
}
string dropDbQuery = $"DROP DATABASE {testDatabase}";
using (var dropCommand = new SqlCommand(dropDbQuery, connection))
{
dropCommand.ExecuteNonQuery();
}
}
}
// テスト用データベースの作成
string createDbQuery = $"CREATE DATABASE {testDatabase}";
using (var command = new SqlCommand(createDbQuery, connection))
{
command.ExecuteNonQuery();
}
// テスト用テーブルの作成
string useDbQuery = $"USE {testDatabase}";
string createTableQuery = "CREATE TABLE TestTable (date DATETIME NOT NULL, num INT NOT NULL)";
using (var command = new SqlCommand($"{useDbQuery}; {createTableQuery}", connection))
{
command.ExecuteNonQuery();
}
}
}
[TestMethod]
public void InsertData_InsertsCorrectly()
{
// Arrange
var testConnectionString = $"Server={server};Database={testDatabase};User Id={username};Password={password};";
var dataInserter = new DataInserter(server, testDatabase, username, password);
var testDate = new DateTime(2021, 1, 1);
int testNum = 1;
// Act
dataInserter.InsertData(testDate, testNum);
// Assert
using (var connection = new SqlConnection(testConnectionString))
{
connection.Open();
string selectQuery = "SELECT date, num FROM TestTable WHERE num = @Value2";
using (var command = new SqlCommand(selectQuery, connection))
{
command.Parameters.AddWithValue("@Value2", testNum);
using (var reader = command.ExecuteReader())
{
Assert.IsTrue(reader.Read()); // レコードが存在することを確認
Assert.AreEqual(testDate, reader.GetDateTime(0)); // 日付が一致することを確認
Assert.AreEqual(testNum, reader.GetInt32(1)); // num が一致することを確認
}
}
}
}
[TestCleanup]
public void Cleanup()
{
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// データベースへのすべての接続を切断
string alterDbQuery = $"ALTER DATABASE {testDatabase} SET SINGLE_USER WITH ROLLBACK IMMEDIATE";
using (var alterCommand = new SqlCommand(alterDbQuery, connection))
{
alterCommand.ExecuteNonQuery();
}
// テスト用データベースの削除
string dropDbQuery = $"DROP DATABASE {testDatabase}";
using (var command = new SqlCommand(dropDbQuery, connection))
{
command.ExecuteNonQuery();
}
}
}
}
}