MusicStore Unit Tests (1) - MVC, EF, Cache, RequestAborted, User
This commit is contained in:
parent
6efdbc75c7
commit
5f95406fd0
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue