LoginSignup
8
12

More than 3 years have passed since last update.

C#でxUnitテスト備忘録

Posted at

はじめに

最近参加してるPJで初めてがっつりC#をかくことになりました。
その中でUnitテストもお願いね~と言われました。
今回は初めてなりにやってみた備忘録。

環境

  • VisualStudio2019
    • ASP.NET Core

xUnitテストの始め方

こちらのサイトを参考に作っていきました。
書き方がまとまっていてわかりやすかったです。

今回やってみたこと備忘録

データベースの値が正しく更新されているか確認したい…

  • インメモリDBにテストデータを登録してテストすればいい

EntityFrameworkCoreで提供されているインメモリDBを使いました。
インメモリDBとはメモリをデータ保存領域とした、データベースプロバイダです。
先輩のコードをまねして作っていた私はどこにデータが登録されているのかわからず、
ずっと接続先の設定が悪いと思ってました。

実際にかいたコードは以下のとおり

using System;
using Xunit;
using Microsoft.EntityFrameworkCore;

namespace Tests
{
    public class MyDbContextFixture : IDisposable
    {
        public DbContextOptions<MyDBContextName> Options;
        public MyDBContextName Context;

        public MyDbContextFixture ()
        {
            Options = new DbContextOptionsBuilder<MyDBContextName>()
                .UseInMemoryDatabase(databaseName: "MyDatabaseName")
                .Options;
            Context = new MyDBContextName(Options);
        }
        public void Dispose()
        {
            Context.Dispose();
        }


    }

テストコードはこちら。
内容は、データベースに登録したステータスコードが60に更新されるかを確認するものです。
テストしたいメソッドの返却値が更新対象のIDのみを返却するので、
そのIDをもとに再検索をかけて確認しています。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
using Newtonsoft.Json;
// テストしたいプロジェクトを参照するのを忘れずに

namespace Tests.Functions
{
        /// <summary>
        /// <see cref="Function{TDbContext}">のテストクラス
        /// </summary>
        public class FunctionTest : IClassFixture<MyDbContextFixture>, IDisposable
        {
            private readonly ITestOutputHelper _output;
            private readonly MyDbContextFixture _fixture;
            private readonly MyDBContextName _context;
            public FunctionTest(MyDbContextFixture fixture, ITestOutputHelper output)
            {
                _output = output;
                _fixture = fixture;
                _context = fixture.Context;
            }

        // ご自身で引数のテストデータ作成します

        // DBに登録したいテストデータをいれます
        // GetTestData()

        /// <summary>
        /// テストデータを削除
        /// </summary>
        void IDisposable.Dispose()
        {
            var list = _context.PrPrint.ToList<PrPrint>();
            _context.PrPrint.RemoveRange(list);
            _context.SaveChanges();
        }


        /// <summary>
        /// ステータスコードが60から70に更新
        /// </summary>
        [Theory(DisplayName = "ステータスコード更新")]
        [MemberData(nameof(MyTestDataName))]
        public void UpdateTest(inputModel)
        {
            var function = new TestFunction<MyDBContextName>(_context);
            // テストデータをInsert
            var list = GetTestData();
            _context.TestTable.AddRange(GetTestData());
            _context.SaveChanges();

            // テストしたい内容
            var result = function.Update_Test(inputModel);
            _output.WriteLine(JsonConvert.SerializeObject(result));
            var entity = _context.TestTable.Where(x => x.Id == result.Id).SingleOrDefault();
            // DBのステータスコードが70
            Assert.Equal("70", entity.StatusCd);
        }
    }
}

例外の種類とメッセージが正しいか確認したい…

  • Assert.Throwsで例外情報を取得。その後に、Assert.Equalなどでメッセージとの整合性を確認。
        /// <summary>
        /// ステータスコードが69
        /// </summary>
        [Theory(DisplayName = "ステータスコード更新")]
        [MemberData(nameof(MyTestDataName))]
        public void UpdateError(TestModel inputModel)
        {
            var function = new TestFunction<MyDBContextName>(_context);
            // テストデータをInsert
            var list = GetTestData();
            _context.PrPrint.AddRange(GetTestData());
            _context.SaveChanges();
            var ex = Assert.Throws<ApplicationException>(() =>
            {
                function.Update_Test(inputModel);
            });
            Assert.IsType<ApplicationException>(ex);
            Assert.Equal("状態69であるデータの更新はできません", ex.Message);
        }

やってみて

インメモリDBは割とテストに使えて便利だなと思いました。
今回初めてプロジェクト内でテストコードをがっつり書いたのですが、
テストコードを書くのに一苦労という感じでした。
でも、テストのデバック実行もできるので、今後使いこなしていきたいなという印象です。
今後また先輩から得た知識を備忘録として追記していく予定です。

参考

8
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
12