MusicStore Unit Tests (1) - MVC, EF, Cache, RequestAborted, User

This commit is contained in:
ianhong 2015-02-25 18:00:19 -08:00
parent 6efdbc75c7
commit 5f95406fd0
3 changed files with 316 additions and 1 deletions

View File

@ -29,8 +29,13 @@ namespace MusicStore.Controllers
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddressAndPayment(Order order, CancellationToken requestAborted)
public async Task<IActionResult> AddressAndPayment([FromForm] Order order, CancellationToken requestAborted)
{
if (!ModelState.IsValid)
{
return View(order);
}
var formCollection = await Context.Request.ReadFormAsync();
try

View File

@ -0,0 +1,179 @@
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Core;
using Microsoft.AspNet.Http.Core.Collections;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using MusicStore.Models;
using Xunit;
namespace MusicStore.Controllers
{
public class CheckoutControllerTest
{
private readonly IServiceProvider _serviceProvider;
public CheckoutControllerTest()
{
var services = new ServiceCollection();
services.AddEntityFramework()
.AddInMemoryStore()
.AddDbContext<MusicStoreContext>();
_serviceProvider = services.BuildServiceProvider();
}
[Fact]
public void AddressAndPayment_ReturnsDefaultView()
{
// Arrange
var controller = new CheckoutController();
// Act
var result = controller.AddressAndPayment();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
}
[Fact]
public async Task AddressAndPayment_ReturnsOrderIfInvalidPromoCode()
{
// Arrange
var context = new DefaultHttpContext();
// AddressAndPayment action reads the Promo code from FormCollection.
context.Request.Form =
new FormCollection(new Dictionary<string, string[]>());
var controller = new CheckoutController();
controller.ActionContext.HttpContext = context;
// Do not need actual data for Order; the Order object will be checked for the reference equality.
var order = new Order();
// Act
var result = await controller.AddressAndPayment(order, CancellationToken.None);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
Assert.NotNull(viewResult.ViewData);
Assert.Same(order, viewResult.ViewData.Model);
}
[Fact]
public async Task AddressAndPayment_ReturnsOrderIfRequestCanceled()
{
// Arrange
var context = new DefaultHttpContext();
context.Request.Form =
new FormCollection(new Dictionary<string, string[]>());
var controller = new CheckoutController();
controller.ActionContext.HttpContext = context;
var order = new Order();
// Act
var result = await controller.AddressAndPayment(order, new CancellationToken(true));
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
Assert.NotNull(viewResult.ViewData);
Assert.Same(order, viewResult.ViewData.Model);
}
[Fact]
public async Task AddressAndPayment_ReturnsOrderIfInvalidOrderModel()
{
// Arrange
var controller = new CheckoutController();
controller.ModelState.AddModelError("a", "ModelErrorA");
var order = new Order();
// Act
var result = await controller.AddressAndPayment(order, CancellationToken.None);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
Assert.NotNull(viewResult.ViewData);
Assert.Same(order, viewResult.ViewData.Model);
}
[Fact]
public async Task Complete_ReturnsOrderIdIfValid()
{
// Arrange
var orderId = 100;
var userName = "TestUserA";
var claims = new List<Claim> { new Claim(ClaimTypes.Name, userName) };
var httpContext = new DefaultHttpContext()
{
User = new ClaimsPrincipal(new ClaimsIdentity(claims)),
};
var dbContext =
_serviceProvider.GetRequiredService<MusicStoreContext>();
dbContext.Add(new Order()
{
OrderId = orderId,
Username = userName
});
dbContext.SaveChanges();
var controller = new CheckoutController()
{
DbContext = dbContext,
};
controller.ActionContext.HttpContext = httpContext;
// Act
var result = await controller.Complete(orderId);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
Assert.NotNull(viewResult.ViewData);
Assert.Equal(orderId, viewResult.ViewData.Model);
}
[Fact]
public async Task Complete_ReturnsErrorIfInvalidOrder()
{
// Arrange
var invalidOrderId = 100;
var dbContext =
_serviceProvider.GetRequiredService<MusicStoreContext>();
var controller = new CheckoutController()
{
DbContext = dbContext,
};
controller.ActionContext.HttpContext = new DefaultHttpContext();
// Act
var result = await controller.Complete(invalidOrderId);
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal("Error", viewResult.ViewName);
}
}
}

View File

@ -0,0 +1,131 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.Data.Entity;
using Microsoft.Framework.Cache.Memory;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using MusicStore.Models;
using Xunit;
namespace MusicStore.Controllers
{
public class HomeControllerTest
{
private readonly IServiceProvider _serviceProvider;
public HomeControllerTest()
{
var services = new ServiceCollection();
services.AddEntityFramework()
.AddInMemoryStore()
.AddDbContext<MusicStoreContext>();
_serviceProvider = services.BuildServiceProvider();
}
[Fact]
public void Error_ReturnsErrorView()
{
// Arrange
var controller = new HomeController();
var errorView = "~/Views/Shared/Error.cshtml";
// Act
var result = controller.Error();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal(errorView, viewResult.ViewName);
}
[Fact]
public async Task Index_GetsSixTopAlbums()
{
// Arrange
var controller = new HomeController()
{
DbContext = _serviceProvider.GetRequiredService<MusicStoreContext>(),
Cache = _serviceProvider.GetRequiredService<IMemoryCache>(),
};
PopulateData(controller.DbContext);
// Action
var result = await controller.Index();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Null(viewResult.ViewName);
Assert.NotNull(viewResult.ViewData);
Assert.NotNull(viewResult.ViewData.Model);
var albums = Assert.IsType<List<Album>>(viewResult.ViewData.Model);
Assert.Equal(6, albums.Count);
}
[Fact]
public void StatusCodePage_ReturnsStatusCodePage()
{
// Arrange
var controller = new HomeController();
var statusCodeView = "~/Views/Shared/StatusCodePage.cshtml";
// Action
var result = controller.StatusCodePage();
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal(statusCodeView, viewResult.ViewName);
}
private void PopulateData(DbContext context)
{
var albums = TestAlbumDataProvider.GetAlbums();
foreach (var album in albums)
{
context.Add(album);
}
context.SaveChanges();
}
private class TestAlbumDataProvider
{
public static Album[] GetAlbums()
{
var generes = Enumerable.Range(1, 10).Select(n =>
new Genre()
{
GenreId = n,
Name = "Genre Name " + n,
}).ToArray();
var artists = Enumerable.Range(1, 10).Select(n =>
new Artist()
{
ArtistId = n + 1,
Name = "Artist Name " + n,
}).ToArray();
var albums = Enumerable.Range(1, 10).Select(n =>
new Album()
{
Artist = artists[n - 1],
ArtistId = n,
Genre = generes[n - 1],
GenreId = n,
}).ToArray();
return albums;
}
}
}
}