簡體   English   中英

ASP.NET MVC異步控制器方法測試

[英]Asp.net mvc async controller method tests

我一直在嘗試學習單元測試,而不是在TDD中學習控制器中的單元測試方法。 我有Unity 3.5,Asp.Net MVC 5.1,實體框架6.1.2,MS測試,NSubstitute 1.8.1.0和Visual Studio 2013 Update3。我有一個包含3個項目的解決方案,一個是普通的MVC 5項目,一個是單元測試項目。和一個類庫都被正確引用並且可以正常工作。 我的代碼可以編譯,一切都很好。 我現在正在嘗試測試我的異步索引操作,這就是我的問題所在。 我遵循了有關EF6測試的msdn文檔,因此我有一個從Context創建的接口,並在控制器中使用了該接口,如下所示:

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());
    }

我使用NSubstitute DbSet / IQueryable <T>的技巧創建了一個TestDbAsyncEnumerator和TestDbAsyncQueryProvider。 因此,煩人的事情是為了測試該索引方法該做什么? 這是我走了多遠:

[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的任務,因此我要反對什么? 我了解到您針對一個模擬進行斷言並使用存根來滿足依賴關系。 那我該怎么辦? 我讀過的單元測試是必經之路,我不想放棄,那么我該怎么辦? 請幫忙?!

我認為從我所看到的情況來看,您可能使事情變得過於復雜。 我認為測試的想法是將所有內容分解為最簡單的形式(單位)。 因此,我可能會以編程方式創建Account,Bank等實例以進行測試。 這樣做的原因是要測試您的邏輯是否按照它所說的做,而不更改數據,如果您使用數據庫,可能會發生更改。

通過EF測試,我將檢查是否從每個結果集中返回了任何項目。

我還將測試您要執行的基本EF操作,即是否返回所有銀行?是否返回所有帳戶?是否可以創建銀行?可以創建帳戶等等。

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

本質上,您要檢查其是否通過,並且需要定義使測試通過或失敗的原因。

這可能像這樣簡單:

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

在測試表格時,與之集成的Selenium也可能非常有用。

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM