前提・実現したいこと
ASP.NET MVCのEntityFrameworkで、Model中のEnumのプロパティをNULL許容にすると
Unitテスト時の手動トランザクション(DbContext)でエラーしてしまい困っています。
下記のコードでは、Unitテスト時はトランザクションを設定しても、ダミーリポジトリを使用するようにしているため、DB操作を行わないようにしてます。
usingの時に例外が発生します。型 'System.NullReferenceException' の初回例外が WebApplication.dll で発生しました。
ただし、nullを設定している箇所がないか見直しましたが、見つかりません。
または、他の方法として、ユニットテスト時に、手動のトランザクションをダミーでも実行できればと考えています。
発生している問題・エラーメッセージ
C#
1public class A_Master { 2 public int Id { get; set; } 3 public string name { get; set; } 4 public B_Enum B { get; set; } 5 6 // NULL許容にするとユニットテストの手動トランザクション時にエラーする 7 // public B_Enum? B { get; set; } 8} 9 10public enum B_Enum { 11 B1 = 1, 12 B2 = 2 13} 14 15public class A_MasterController : Controller { 16 private readonly UnitOfWork unitOfWork; 17 18 // Default constructor 19 public A_MasterController() { 20 this.unitOfWork = new UnitOfWork(); 21 } 22 23 // Unit testing use 24 public A_MasterController(UnitOfWork dummyRepositoryUnitOfWork) { 25 this.unitOfWork = dummyRepositoryUnitOfWork; 26 } 27 28 public async Task<ActionResult> Test() { 29 30 // ユニットテスト時に usingのthis.unitOfWork.ApplicationDbContextでエラーする 31 using (var dbContextTransaction = this.unitOfWork.ApplicationDbContext.Database.BeginTransaction()) { 32 // DB操作 33 34 } 35 } 36} 37 38public class UnitOfWork : IDisposable { 39 private readonly ApplicationDbContext context = new ApplicationDbContext(); 40 41 public IA_MasterRepository A_MasterRepository { get; private set; } 42 43 public ApplicationDbContext ApplicationDbContext { 44 get { return this.context; } 45 } 46 47 public UnitOfWork() { 48 this.A_MasterRepository = new A_MasterRepository(context); 49 } 50 51 public UnitOfWork(IA_MasterRepository dummyA_MasterRepository) { 52 this.A_MasterRepository = dummyA_MasterRepository; 53 } 54} 55 56// 【追記】IdentityModelのApplicationDbContext 57public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { 58 public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { 59 60 } 61 62 public static ApplicationDbContext Create() { 63 return new ApplicationDbContext(); 64 } 65 66 public DbSet<A_Master> A_Masters { get; set; } 67}
【追記】ユニットテストの状況
・EnumプロパティをNULL許容にしない場合
・EnumプロパティをNULL許容にした場合、全体(他のテストにも)に影響
【追記】EnumのNULL許容について
マスタ以外のEnumのNULL許容は問題ありませんでした。
マスタの1モデルのEnumのNULL許容でこの問題が発生していますので、
上記のコードでは再現ができないかもしれません。
一旦、ApplicationDbContextを標準のままに戻し、DbContext用クラスを別に用意しました。
public class TestDbContext : DbContext {
public TestDbContext() : base("TestConnection") { }
public DbSet<A_Master> A_Masters { get; set; }
}
【追記】
ApplicationDbContextを標準のものに戻し、ASP.NET Identity用のデータベースと、通常のModelでデータベースを分けるところまで実施しました。
2つのデータベースと、テーブルを作る部分までは問題ありませんでしたが、
モデルのEnumの部分での変化はありませんでした。
その他に試したこととして、
・モデルを1つにしても、ユニットテスト時に手動トランザクションでエラーがしてました。
・手動トランザクションのエラーがしない状態の時のプロジェクトファイルを、違うパソコンで実行すると手動トランザクションのエラーが発生
・コマンドでのテーブル作成時にはコマンドエラーはしない
他の方法として、ユニットテスト時に、手動のトランザクションをダミーでも実行できればと考えています。
最小構成でモデルを1つにした時でも同様のエラーが出ています。
NullReferenceExceptionは発生しなくなりました。
C#
1public async Task<ActionResult> Create() { 2 // ユニットテスト時、usingの行でエラー 3 using (var dbContextTransaction = this.unitOfWork.TestDbContext.Database.BeginTransaction()) { 4 Debug.WriteLine("Do"); 5 6 dbContextTransaction.Commit(); 7 }; 8 9 /* 10 // ユニットテスト時、UnitOfWorkを使用せず、直接こちらでも実施しても同じエラー 11 // usingの行でエラー 12 var context = new TestSpecificationSystemDbContext(); 13 using (var testContext = context.Database.BeginTransaction()) { 14 Debug.WriteLine("Do"); 15 16 testContext.Commit(); 17 }; 18 */ 19 20 return null; 21}
■ エラー時の出力
txt
1'vstest.executionengine.x86.exe' (CLR v4.0.30319: DefaultDomain): 'C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll' が読み込まれました。シンボルの読み込みをスキップしました。モジュールは最適化されていて、デバッグ オプションの [マイ コードのみ] 設定が有効になっています。 2'vstest.executionengine.x86.exe' (CLR v4.0.30319: DefaultDomain): 'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 12.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\vstest.executionengine.x86.exe' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。 3'vstest.executionengine.x86.exe' (CLR v4.0.30319: vstest.executionengine.x86.exe): 'C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO 12.0\COMMON7\IDE\COMMONEXTENSIONS\MICROSOFT\TESTWINDOW\Microsoft.VisualStudio.TestPlatform.TestExecutor.Core.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。 4...(省略)
補足情報(FW/ツールのバージョンなど)
.NET Framework 4.7.2
C#、ASP.NET MVC5
Visual Studio Express 2012 for Web
あなたの回答
tips
プレビュー