2015-02-06 102 views
0

我一直在努力學習單元測試,不太TDD在那裏我試圖單元測試方法在我的控制器。我有Unity 3.5,Asp.Net MVC 5.1,實體框架6.1.2,MS測試,NSubstitute 1.8.1.0和Visual Studio 2013更新3.我有3個項目的解決方案,一個是正常的MVC 5項目,一個單元測試項目和一個類庫所有引用正常,工作正常。我的代碼編譯好,一切都很好。我現在試圖測試我的異步索引行爲,其中存在我的問題。我也跟着上EF6測試MSDN文檔,所以我有我從我的上下文中創建和使用,在我的控制,像這樣的接口:Asp.net MVC異步控制器的方法測試

public interface ITestContext : IDisposable 
{ 
    IDbSet<Account> Accounts { get; set; } 
    IDbSet<Bank> Banks { get; set; } 
    DbEntityEntry Entry(object o); 
    int SaveChanges(); 
    Task<int> SaveChangesAsync(); 
} 

然後我的上下文類是像這樣:

public class TestContext : DbContext, ITestContext 
{ 
    public TestContext(): base("DefaultConnection"){} 

    public virtual IDbSet<Account> Accounts { get; set; } 
    public virtual IDbSet<Bank> Banks { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 
     base.OnModelCreating(modelBuilder); 
    } 
    public override int SaveChanges() 
    { 
     return base.SaveChanges(); 
    } 

    public override Task<int> SaveChangesAsync() 
    { 
     return base.SaveChangesAsync(); 
    } 

    public DbEntityEntry Entity(object o) 
    { 
     return base.Entry(o); 
    } 
} 

所以我在使用DI的控制器中使用接口。我所有的控制方法是異步方法,使我的索引動作看起來像這樣:

public class AccountsController : Controller 
{ 
    private ITestContext db; 

    public AccountsController(ITestContext _db) 
    { 
     db = _db; 
     //db1 = bnk; 
    } 

    // GET: Accounts 
    public async Task<ActionResult> Index() 
    { 
     var accounts = db.Accounts.Include(a => a.Bank); 
     return View(await accounts.ToListAsync()); 
    } 

我創建了一個TestDbAsyncEnumerator和TestDbAsyncQueryProvider採取提示從NSubstitute DbSet/IQueryable<T>。所以煩人的事情是爲了測試這個索引方法該怎麼做?這是我走了多遠:

[TestMethod] 
    public async Task TestingIndexControllerAction() 
    { 
     var testdb = new List<Account> 
     { 
      new Account{ Bank=new Bank{Name="Zenith"}, AccountBalance=19000, AccountName="John Doe"} 
     }.AsQueryable(); 
     var test = Substitute.For<IDbSet<Account>, IDbAsyncEnumerable<Account>>().Initailize(testdb); 
     var context = Substitute.For<ITestContext>(); 
     context.Accounts.Returns(test); 
     var controller = new AccountsController(context); 
     var result = await controller.Index(); 
    } 

有人能幫我解決這個問題,並指出我在正確的方向嗎?我已經閱讀過博客和一本書,但仍然無法理解我應該在這裏做什麼?結果是一個ActionResult的任務,所以我主張什麼?我已經瞭解到,你堅持反對模擬並使用存根來滿足依賴關係。那麼我該怎麼辦?我讀過的單元測試是要走的路,我不想放棄,所以我在這裏做什麼?請幫忙?!

+0

如果你不明白你應該做什麼,那麼SO是錯誤的地方來幫助你 - 你應該把你的問題變成更具體的東西,比如「我想檢查XXXX和YYYY」...... – 2015-02-06 01:15:28

+0

你能否請澄清你的代碼示例中「結果是ActionResult的任務」的位置? – 2015-02-06 01:15:56

回答

1

我覺得你從我所看到的可能是過於複雜的事情。我所看到的測試理念是將所有東西都打破成最簡單的形式(單位)。所以我可能會爲了測試目的而編程創建Account,Bank等實例。原因是爲了測試你的邏輯是否正在做它所說的沒有數據變化的情況,如果你使用數據庫的話會發生這種情況。

隨着EF的測試,我會檢查,看看是否有任何物品從每個結果集返回。

另外我想測試要執行基本EF操作,即它返回所有銀行?它返回所有帳戶?您可以創建一個銀行?您可以創建一個帳戶等等。

我使用NUnit,但大多數的單元測試框架是相似的。

從本質上說要檢查,看看它的通過與否,你需要定義什麼樣的測試合格或不合格。

這可能是這麼簡單的東西:

Assert.IsTrue(result.Equals("Hello World")); 

而且硒這種集成測試表單時是非常有用的。

希望有所幫助。