パソコン練習日記

やってみたことを記録しています。Bloggerからこちらに引っ越して来ました。一部、画像がリンク切れしていますがひとつひとつ直すのは心が折れたのでそのままにします。

Visual Studioとコンテナを使ったCICDお勉強の記録2 とりあえず単体テストが動くようになるまで

これの続き

今度は、とりあえず単体テストが動くようになるまでをやっていく

単体テストを追加

ソリューションを右クリックし、「追加」 > 「新しいプロジェクト」を選択

MSTest、NUnit、xUnitとかある。 どれ使えばいいのかわからん。

Bingチャットに相談してみて、「ユニットテストの基本的な概念は同じであるため、一つを学べば他のフレームワークも理解しやすくなるし、とりあえずどれでもいいと思うよ。」という結論になり、MSTestで行くことにした。

Testプロジェクトの名前は"DatabaseOperationTests"にしとく。

メインプログラムのプロジェクトの名前を"SQLDB_SimpleTests"していたので、どちらがテストプロジェクトなのかわかりづらい。失敗したと思った。

単体テストプロジェクトからメインプログラムのプロジェクト参照追加

テストプロジェクトを右クリック、「追加」>「プロジェクト参照」

テスト対象のプロジェクト"SQLDB_SimpleTests"を参照

テスト対象のプログラムのnamespace名をテストのほうでusing

単体テストとテスト対象プログラムのリファクタリング

テストプログラムをとりあえず以下な感じに

テスト対象のプログラムが今はProgramクラスのMainメソッドだけど、データをInsertするプログラムなので、DataInserterクラスに変更する前提でテストを作る。


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};";
        }

 

        [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 が一致することを確認
                    }
                }
            }
        }
    }
}

テスト対象プログラムもテストし易いようにリファクタリング

using System;
using System.Data.SqlClient;

namespace SqlServerOperation
{
    class Program
    {
        static void Main(string[] args)
        {
            var dataInserter = new DataInserter("192.168.10.13,1433", "TestDB", "sa", "P@$$w0rd");
            dataInserter.InsertData(DateTime.Now, 1);
        }
    }

    public class DataInserter
    {
        private readonly string _connectionString;

        public DataInserter(string server, string database, string username, string password)
        {
            _connectionString = $"Server={server};Database={database};User Id={username};Password={password};";
        }

        public void InsertData(DateTime date, int num)
        {
            using (var connection = new SqlConnection(_connectionString))
            {
                connection.Open();

                string insertQuery = "INSERT INTO TestTable (date, num) VALUES (@Value1, @Value2)";
                using (var command = new SqlCommand(insertQuery, connection))
                {
                    command.Parameters.AddWithValue("@Value1", date);
                    command.Parameters.AddWithValue("@Value2", num);
                    command.ExecuteNonQuery();
                }
            }
        }
    }
}

テスト実行前に今DBのテーブルにあるデータを削除

USE [TestDB]
GO
 
/****** Object:  Table [dbo].[TestTable]    Script Date: 2024/01/01 14:29:32 ******/
IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestTable]') AND type in (N'U'))
DROP TABLE [dbo].[TestTable]
GO
 
/****** Object:  Table [dbo].[TestTable]    Script Date: 2024/01/01 14:29:32 ******/
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
CREATE TABLE [dbo].[TestTable](
[date] [datetime] NOT NULL,
[num] [int] NOT NULL
) ON [PRIMARY]
GO

テスト実行

テスト完了

DBも一応確認。テストデータがちゃんと登録されている