I have been trying to learn unit testing, not quite TDD where I am trying to unit test methods in my controllers. I have Unity 3.5, Asp.Net MVC 5.1, Entity Framework 6.1.2, MS Tests, NSubstitute 1.8.1.0 and Visual Studio 2013 Update 3. I have a solution with 3 projects, One a normal MVC 5 project, a Unit Test project and a class Library all referenced properly and working fine. My code compiles alright and everything is well. I am now trying to Test my async index action and therein lies my issues. I followed the msdn documentation on EF6 testing so I have an Interface that I created from my Context and used that in my controller like so:
public interface ITestContext : IDisposable
{
IDbSet<Account> Accounts { get; set; }
IDbSet<Bank> Banks { get; set; }
DbEntityEntry Entry(object o);
int SaveChanges();
Task<int> SaveChangesAsync();
}
Then my context class is like so:
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);
}
}
so I use the Interface in my controller using DI. All my controller methods are async methods so my index action looks like so:
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());
}
I created a TestDbAsyncEnumerator and TestDbAsyncQueryProvider taking tips from NSubstitute DbSet / IQueryable<T>. So the annoying thing is what to do in order to test this index method? This is how far I have come:
[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();
}
Can someone please help me figure this out and point me in the right direction? I have read blogs and a book but still can't understand what I should be doing here? result is a Task of ActionResult so what am I asserting against? I have learned that you assert against a mock and use stubs to satisfy dependencies. so then what do I do? Unit testing I have read is the way to go and I don't want to give up so what do I do here? Please help?!