2017-10-16 20 views
1

.NET Framework 4.6.1およびEF6を使用したASP.NETコアプロジェクトがあります。 EF6を使用するためのメモリ内SQLiteデータベースを構成するために、単体テストを書いて、すでに時間を費やしたいと思います。しかし、それは動作しません。EF6(Entity Framework 6)を使用した単体テストの作成

質問はどのように私は私のプロジェクトをテストすることができますか?

私の現在のコード:

public class DataAccessLayer : DbContext 
{ 
    public DataAccessLayer(string connectionString) 
    : base(connectionString) { 
    } 

    public DataAccessLayer(DbConnection connection) 
    : base(connection, true) { 
    } 

    public DbSet<User> Users { get; set; } 

    public DbSet<Setting> Settings { get; set; } 

    public DbSet<UserRole> UserRoles { get; set; } 

    public DbSet<MainKey> MainKeys { get; set; } 
} 

[Table("Users")] 
public class User 
{ 
    [Key] 
    [Required] 
    public int UserID { get; set; } 

    [Required][StringLength(50)] 
    public string UserName { get; set; } 

    ... 
} 

public class Testbase 
{ 
    protected DataAccessLayer Context { get; private set; } 

    [TestInitialize] 
    public virtual void SetUp() 
    { 
    var connection = this.CreateConnection(); 
    connection.Open(); 
    this.Context = new DataAccessLayer(connection); 
    this.Context.Database.CreateIfNotExists(); 
    } 

    private SQLiteConnection CreateConnection() { 
    var connectionStringBuilder = new SQLiteConnectionStringBuilder { DataSource = ":memory:" }; 
    return new SQLiteConnection(connectionStringBuilder.ToString()); 
    } 
} 

私は、ユーザーを追加しようとすると、私はエラーを以下の取得:

System.Data.SQLite.SQLiteException: SQL logic error or missing database no such table: Users.

私は私のテーブルはthis.Context.Database.CreateIfNotExists();を呼び出すことによって生成されたを想定、または私はそれについて誤解していますか?

+0

質問には答えられませんが、https://github.com/tamasflamich/effortを考慮する必要があります – Jim

+0

FWIW、メモリデータベースまたはいいえ、これは単体テストではありません。 *統合テスト*です。その点では、実際のサイトが実行されているDBプラットフォーム(SQLiteではなくSQL Serverなど)を実際に使用する必要があります。 –

答えて

2

は、それはユニットテストのために使用され、シンプルで高速なインメモリ・データベースであるNugetパッケージ努力に

を使用することを検討してください。

空のデータベースを使用してデータベースを開始し、データベースシーダーを使用して入力するか、テストCSVファイルの値を入力することができます。

は、ブログや記事を使用して、データベースとのTutorials Effort - Entity Framework Unit Testing Tool

簡単な例を参照してください。ブログと投稿の一対多の関係

public class Blog 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    public virtual ICollection<Post> Posts { get; set; } 
} 

public class Post 
{ 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string Content { get; set; } 

    public int BlogId { get; set; } 
    public virtual Blog Blog { get; set; } 
} 

public class BloggingContext : DbContext 
{ 
    public BloggingContext() : base() { } // constructor using config file 

    public BloggingContext(string nameOrConnectionString) : base(nameOrConnectionString) { } 
    public BloggingContext(DbConnection connection) : base(connection, true) { } 
    public DbSet<Blog> Blogs { get; set; } 
    public DbSet<Post> Posts { get; set; } 
} 

あなたは接続文字列を取得せず、代わりにDbConnectionを取得します。したがって、BloggingContextの2番目のコンストラクタです。スーパークラスに渡されたブール値は、dbcontextに接続を所有していることを伝えるために、DbContextがDisposedのときに接続を閉じてDisposeする必要があります。

これは、通常のDbContextの使用との唯一の違いです。 DbContextとDbSetsへの他のすべての呼び出しは正常です。

static void Main(string[] args) 
{ 
    var connection = Effort.DbConnectionFactory.CreateTransient(); 

    using (var dbContext = new BloggingContext(connection)) 
    { 
     var addedBlog = dbContext.Blogs.Add(new Blog[] 
     { 
      Name = "1", 
      Posts = new Post[] 
      { 
       new Post() {Title = "1st", Content = "a"}, 
       new Post() {Title = "2nd", Content = "b"}, 
       new Post() {Title = "3rd", Content = "c"}, 
      }, 
     }); 
     dbContext.SaveChanges(); 
    } 

    using (var dbContext = new BloggingContext(connection)) 
    { 
     var allPosts = context.Posts.ToList(); 
     foreach (var post in allPosts) 
     { 
      Console.WriteLine($"{post.Id}: {post.Title}"); 
     } 
    } 

1つの先端:それを現像してテストが原因で誤った試験(データ)のため、または試験されている不正なコードの失敗かどうかを確認することが困難な場合があるが。テスト中にデータベース内の内容をデバッグ中にチェックするのはかなり困難です。したがって、私はテスト値でいっぱいになった実際のデータベースを使ってテストを開発する傾向があります。テストのデバッグがほとんど必要ない場合は、メモリ内のデータベースに切り替えます。実際、私にとってこれは2番目または3番目のDbContextコンストラクタ間の切り替えです

+0

私はこの単純なコードラインでうわー!それは今働いています:)ありがとうございました! –

関連する問題