Last active
August 29, 2015 14:18
-
-
Save gcollic/8fb21683c838d8794389 to your computer and use it in GitHub Desktop.
MVC test helpers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using BoDi; | |
using Meltingood.Web.App_Start; | |
using Ninject.MockingKernel.NSubstitute; | |
using TechTalk.SpecFlow; | |
namespace Tests | |
{ | |
[Binding] | |
public class Config | |
{ | |
private readonly IObjectContainer _objectContainer; | |
public Config(IObjectContainer objectContainer) | |
{ | |
_objectContainer = objectContainer; | |
MapperConfig.Config(); | |
} | |
[BeforeScenario] | |
public void Initialize() | |
{ | |
var kernel = new NSubstituteMockingKernel(); | |
_objectContainer.RegisterInstanceAs(kernel); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
using System.Web.Mvc; | |
using NUnit.Framework; | |
namespace Tests.Helper | |
{ | |
// Modified version of https://gist.github.com/RhysC/8329873 | |
public static class ControllerTestExtensions | |
{ | |
public static TAttribute Has<TAttribute>(this Controller controller) where TAttribute : Attribute | |
{ | |
var attribute = controller.GetType().GetCustomAttributes<TAttribute>().Single(); | |
Assert.NotNull(attribute); | |
return attribute; | |
} | |
public static TAttribute With<TAttribute>(this TAttribute attribute, Func<TAttribute, bool> predicate) where TAttribute : Attribute | |
{ | |
Assert.True(predicate(attribute)); | |
return attribute; | |
} | |
public static MethodInfo Action<TController>(this TController controller, Expression<Func<TController, ActionResult>> expression) | |
{ | |
var methodCall = expression.Body as MethodCallExpression; | |
if (methodCall == null) throw new InvalidOperationException("Expression body is expected to be a MethodCallExpression. This is design for Action on Controllers which must be methods."); | |
return methodCall.Method; | |
} | |
public static T Has<T>(this MethodInfo methodInfo) where T : Attribute | |
{ | |
var att = methodInfo.GetCustomAttributes(typeof(T), true).Single(); | |
Assert.NotNull(att); | |
return att as T; | |
} | |
public static TResult Is<TResult>(this ActionResult actionResult) where TResult : ActionResult | |
{ | |
Assert.IsAssignableFrom<TResult>(actionResult); | |
return actionResult as TResult; | |
} | |
public static TResult HasViewName<TResult>(this TResult viewResult, string viewName) where TResult : ViewResult | |
{ | |
Assert.AreEqual(viewName, viewResult.ViewName); | |
return viewResult; | |
} | |
public static TResult HasViewModel<TResult>(this TResult viewResult, object viewModel) where TResult : ViewResult | |
{ | |
Assert.AreEqual(viewModel, viewResult.Model); | |
return viewResult; | |
} | |
public static TResult WithViewModel<TResult, TModel>(this TResult viewResult, Action<TModel> viewModelAssertions = null) where TResult : ViewResult where TModel : class | |
{ | |
Assert.IsAssignableFrom<TModel>(viewResult.Model); | |
if (viewModelAssertions != null) | |
{ | |
viewModelAssertions.Invoke(viewResult.Model as TModel); | |
} | |
return viewResult; | |
} | |
public static TResult HasViewBagProperty<TResult>(this TResult viewResult, string viewBagPropertyName, object expectedPropertyValue) where TResult : ViewResult | |
{ | |
return viewResult.HasViewDataProperty(viewBagPropertyName, expectedPropertyValue);//Viewdata is just the string dict of the view bag | |
} | |
public static TResult HasViewDataProperty<TResult>(this TResult viewResult, string viewBagPropertyName, object expectedPropertyValue) where TResult : ViewResult | |
{ | |
Assert.AreEqual(expectedPropertyValue, viewResult.ViewData[viewBagPropertyName]); | |
return viewResult; | |
} | |
public static TResult HasModelStateErrorMessage<TResult>(this TResult viewResult, string modelStateErrorKey, object expectedErrorMessage) where TResult : ViewResult | |
{ | |
Assert.AreEqual(expectedErrorMessage, viewResult.ViewData.ModelState.Single(msd => msd.Key == modelStateErrorKey).Value.Errors.Single().ErrorMessage); | |
return viewResult; | |
} | |
public static TResult HasModelStateErrorMessage<TResult>(this TResult viewResult, params string[] modelStateErrorKeys) where TResult : ViewResult | |
{ | |
foreach (var errorKey in modelStateErrorKeys) | |
{ | |
Assert.IsTrue(viewResult.ViewData.ModelState.ContainsKey(errorKey)); | |
} | |
return viewResult; | |
} | |
public static TResult HasModelStateError<TResult>(this TResult viewResult) where TResult : ViewResult | |
{ | |
Assert.IsTrue(viewResult.ViewData.ModelState.Any()); | |
return viewResult; | |
} | |
public static TResult HasRedirectUrl<TResult>(this TResult redirectResult, string expectedUrl) where TResult : RedirectResult | |
{ | |
Assert.AreEqual(expectedUrl, redirectResult.Url); | |
return redirectResult; | |
} | |
public static TResult HasActionName<TResult>(this TResult redirectResult, string expectedName) where TResult : RedirectToRouteResult | |
{ | |
Assert.AreEqual(expectedName, redirectResult.RouteValues["action"]); | |
return redirectResult; | |
} | |
public static TResult HasRouteValues<TResult>(this TResult redirectResult, object expectedValues) where TResult : RedirectToRouteResult | |
{ | |
//Assume this is an Anon object | |
var properties = expectedValues.GetType().GetProperties(); | |
foreach (var propertyInfo in properties) | |
{ | |
var expectedValue = propertyInfo.GetValue(expectedValues, null); | |
Assert.AreEqual(expectedValue, redirectResult.RouteValues[propertyInfo.Name]); | |
} | |
return redirectResult; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Data.Entity; | |
using System.Linq; | |
using System.Linq.Expressions; | |
namespace Tests.Helper | |
{ | |
// Modified version of http://blog.brentmckendrick.com/generic-repository-fake-idbset-implementation-update-find-method-identity-key/ | |
public class FakeDbSet<T> : IDbSet<T> where T : class | |
{ | |
private readonly Func<object[], T, bool> _keyFinder; | |
private readonly Action<T> _keyGenerator; | |
private readonly HashSet<T> _data; | |
private readonly IQueryable _query; | |
public FakeDbSet(Func<object[], T, bool> keyFinder, Action<T> keyGenerator, IEnumerable<T> startData = null) | |
{ | |
_keyFinder = keyFinder; | |
_keyGenerator = keyGenerator; | |
_data = (startData != null ? new HashSet<T>(startData) : new HashSet<T>()); | |
_query = _data.AsQueryable(); | |
} | |
public virtual T Find(params object[] keyValues) | |
{ | |
return this.AsQueryable().SingleOrDefault(x => _keyFinder(keyValues, x)); | |
} | |
public T Add(T item) | |
{ | |
_keyGenerator(item); | |
_data.Add(item); | |
return item; | |
} | |
public T Remove(T item) | |
{ | |
_data.Remove(item); | |
return item; | |
} | |
public T Attach(T item) | |
{ | |
_data.Add(item); | |
return item; | |
} | |
public void Detach(T item) | |
{ | |
_data.Remove(item); | |
} | |
Type IQueryable.ElementType | |
{ | |
get { return _query.ElementType; } | |
} | |
Expression IQueryable.Expression | |
{ | |
get { return _query.Expression; } | |
} | |
IQueryProvider IQueryable.Provider | |
{ | |
get { return _query.Provider; } | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return _data.GetEnumerator(); | |
} | |
IEnumerator<T> IEnumerable<T>.GetEnumerator() | |
{ | |
return _data.GetEnumerator(); | |
} | |
public T Create() | |
{ | |
return Activator.CreateInstance<T>(); | |
} | |
public ObservableCollection<T> Local | |
{ | |
get | |
{ | |
return new ObservableCollection<T>(_data); | |
} | |
} | |
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T | |
{ | |
return Activator.CreateInstance<TDerivedEntity>(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web.Mvc; | |
using Ninject; | |
using Ninject.MockingKernel.NSubstitute; | |
using NSubstitute; | |
using TechTalk.SpecFlow; | |
namespace Tests | |
{ | |
[Binding] | |
public class AfeatureSteps | |
{ | |
private readonly NSubstituteMockingKernel _kernel; | |
private readonly ControllerContext _controllerContext; | |
public AfeatureSteps(NSubstituteMockingKernel kernel) | |
{ | |
_kernel = kernel; | |
_controllerContext = Substitute.For<ControllerContext>(); | |
_kernel.Bind<AFeatureController>().ToSelf().InSingletonScope(); | |
_kernel.Get<AFeatureController>().ControllerContext = _controllerContext; | |
_kernel.Get<AFeatureController>().Url = Substitute.For<UrlHelper>(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment