{"_id":"54485571c1b42e08005b82c1","is_link":false,"category":{"_id":"5447ed118d7af31a00dd411c","__v":5,"pages":["54485515c1b42e08005b82bd","5447ed4d8d7af31a00dd411d","5447ef460319802200fc070d","54485571c1b42e08005b82c1","54af53eb0cf42a0b001d5b73"],"project":"54471fc9e12a270800028adc","version":"54471fc9e12a270800028adf","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2014-10-22T17:44:49.648Z","from_sync":false,"order":3,"slug":"assertions","title":"Assertions"},"project":"54471fc9e12a270800028adc","__v":11,"user":"54471f91beb6320800da6f75","version":{"_id":"54471fc9e12a270800028adf","__v":10,"project":"54471fc9e12a270800028adc","createdAt":"2014-10-22T03:08:57.750Z","releaseDate":"2014-10-22T03:08:57.750Z","categories":["54471fc9e12a270800028ae0","5447b9e7b96a63140077d747","5447be130319802200fc0620","5447ed118d7af31a00dd411c","5447ed230319802200fc0702","5448524c4544c30800241f41","544854504544c30800241f4d","544854af4544c30800241f50","544854e74544c30800241f51","54485557c1b42e08005b82bf"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"updates":["55c9b46824722f3700ce1499","564c23b454d67821002a0ac5"],"next":{"pages":[],"description":""},"createdAt":"2014-10-23T01:10:09.602Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"try":true,"basic_auth":false,"auth":"never","params":[],"url":""},"isReference":false,"order":4,"body":"One of the benefits of ASP.NET MVC over WebForms is that you can actually write automated unit tests against large pieces of your web applications.  However, testing ASP.NET MVC applications isn't as straight-forward as it could be.  The out-of-the-box experience leads to complex test cases.\n\nSpecsFor<Web> Helpers adds additional assertions and fake objects that will help you write cleaner, easier-to-read specs for Controllers, Action Filters, HtmlHelpers, and more.\n\nThe utility of SpecsFor<Web> Helpers is easiest to see when you compare it to specs that *aren't* using  them.  Check out the examples below!\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Testing a ViewResult\"\n}\n[/block]\nWithout SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Test]\\npublic void then_it_says_hello_to_the_user()\\n{\\n  var viewResult = _result.ShouldBeType<ViewResult>();\\n  var model = viewResult.Model.ShouldBeType<SayHelloViewModel>();\\n  model.ShouldLookLike(new SayHelloViewModel\\n                       {\\n                         Name = \\\"John Doe\\\"\\n                       });\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nWith SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Test]\\npublic void then_it_says_hello_to_the_user()\\n{\\n  _result.ShouldRenderDefaultView()\\n    .WithModelLike(new SayHelloViewModel\\n                   {\\n                     Name = \\\"John Doe\\\"\\n                   });\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Testing a RedirectResult\"\n}\n[/block]\nWithout SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Test]\\npublic void then_it_redirects_to_the_say_hello_action()\\n{\\n  var redirectResult = _result.ShouldBeType<RedirectToRouteResult>();\\n  redirectResult.RouteValues[\\\"controller\\\"].ShouldEqual(\\\"Home\\\");\\n  redirectResult.RouteValues[\\\"action\\\"].ShouldEqual(\\\"SayHello\\\");\\n  redirectResult.RouteValues[\\\"name\\\"].ShouldEqual(\\\"Jane Doe\\\");\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nWith SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"[Test]\\npublic void then_it_redirects_to_the_say_hello_action()\\n{\\n  _result.ShouldRedirectTo<HomeController>(\\n    c => c.SayHello(\\\"Jane Doe\\\"));\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Testing an Action Filter\"\n}\n[/block]\nWithout SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"protected override void When()\\n{\\n  var httpContext = new Mock<HttpContextBase>().Object;\\n  var controllerContext = new ControllerContext(httpContext, new RouteData(), new Mock<ControllerBase>().Object);\\n  var reflectedActionDescriptor = new ReflectedActionDescriptor(typeof(ControllerBase).GetMethods()[0], \\\"Test\\\", new ReflectedControllerDescriptor(typeof(ControllerBase)));\\n  _filterContext = new ActionExecutingContext(controllerContext, reflectedActionDescriptor, new Dictionary<string, object>());\\n  SUT.OnActionExecuting(_filterContext);\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nWith SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"protected override void When()\\n{\\n  _filterContext = new FakeActionExecutingContext();\\n  SUT.OnActionExecuting(_filterContext);\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Testing an HtmlHelper\"\n}\n[/block]\nWithout SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class when_creating_a_bootstrap_button : SpecsFor<HtmlHelper>\\n{\\n  private HtmlTag _button;\\n\\n  protected override void InitializeClassUnderTest()\\n  {\\n    var contextMock = new Mock<HttpContextBase>();\\n    contextMock.Setup(x => x.Request).Returns(new Mock<HttpRequestBase>().Object);\\n    var response = new Mock<HttpResponseBase>();\\n    response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s);\\n    contextMock.Setup(x => x.Response).Returns(response.Object);\\n    var viewContext = new ViewContext()\\n    {\\n      HttpContext = contextMock.Object\\n    };\\n    var viewDataContainer = new Mock<IViewDataContainer>().Object;\\n    SUT = new HtmlHelper(viewContext, viewDataContainer);\\n  }\\n\\n  protected override void When()\\n  {\\n    _button = SUT.BootstrapButton(\\\"Submit!\\\");\\n  }\\n\\n  [Test]\\n  public void then_it_creates_submit_button()\\n  {\\n    _button.Attr(\\\"type\\\").ShouldEqual(\\\"submit\\\");\\n  }\\n\\n  [Test]\\n  public void then_it_sets_the_correct_button_classes()\\n  {\\n    _button.HasClass(\\\"btn\\\").ShouldBeTrue();\\n    _button.HasClass(\\\"btn-primary\\\").ShouldBeTrue();\\n  }\\n}\\n\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\nWith SpecsFor<Web> Helpers:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class when_creating_a_bootstrap_button : SpecsFor<FakeHtmlHelper>\\n{\\n  private HtmlTag _button;\\n\\n  protected override void When()\\n  {\\n    _button = SUT.BootstrapButton(\\\"Submit!\\\");\\n  }\\n\\n  [Test]\\n  public void then_it_creates_submit_button()\\n  {\\n    _button.Attr(\\\"type\\\").ShouldEqual(\\\"submit\\\");\\n  }\\n\\n  [Test]\\n  public void then_it_sets_the_correct_button_classes()\\n  {\\n    _button.HasClass(\\\"btn\\\").ShouldBeTrue();\\n    _button.HasClass(\\\"btn-primary\\\").ShouldBeTrue();\\n  }\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"There's more...\"\n}\n[/block]\nSpecsFor<Web> Helpers includes a slew of fake objects you can use, many of which can be configured using SpecsFor's GetMockFor method (even though they aren't actually mock objects!)\n\nHere's a full list of the available fake objects and their corresponding GetMockFor-compatible configuration interface (where applicable):\n\n* FakeActionExecutingContext\n* FakeHtmlHelper\n* FakeHttpContext\n * IFormParamsProvider\n * IHttpContextBehavior\n * IQueryStringParamsProvider\n * IServerVariablesParamsProvider\n * IHeadersParamsProvider \n* FakeHttpRequest\n * ICookieProvider\n * IFormParamsProvider\n * IQueryStringParamsProvider\n * IServerVariablesParamsProvider\n * IHeadersParamsProvider \n* FakeHttpSessionState\n* FakeIdentity\n* FakePrincipal\n* FakeRequestContext\n* FakeUrlHelper\n* FakeViewContext\n* FakeViewDataContainer\n\nIn many cases, you can use the fake objects as-is in your specs.  If you need to configure the behavior of a fake, such as wiring up query string parameters when you're using a FakeHtmlHelper, you can grab the behavior interface using GetMockFor, then configure the behavior that the fake will use:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public class when_getting_the_app_version_and_the_app_is_in_debug_mode : SpecsFor<FakeHtmlHelper>\\n{\\n  private string _version;\\n\\n  protected override void Given()\\n  {\\n    GetMockFor<IHttpContextBehavior>()\\n      .Setup(x => x.IsDebuggingEnabled)\\n      .Returns(true);\\n  }\\n\\n  protected override void When()\\n  {\\n    _version = SUT.GetVersionString();\\n  }\\n\\n  [Test]\\n  public void then_the_version_contains_the_debug_suffix()\\n  {\\n    _version.EndsWith(\\\"DEBUG\\\").ShouldBeTrue();\\n  }\\n}\",\n      \"language\": \"csharp\"\n    }\n  ]\n}\n[/block]","excerpt":"","slug":"specsforweb-helpers","type":"basic","title":"SpecsFor<Web> Helpers"}

SpecsFor<Web> Helpers


One of the benefits of ASP.NET MVC over WebForms is that you can actually write automated unit tests against large pieces of your web applications. However, testing ASP.NET MVC applications isn't as straight-forward as it could be. The out-of-the-box experience leads to complex test cases. SpecsFor<Web> Helpers adds additional assertions and fake objects that will help you write cleaner, easier-to-read specs for Controllers, Action Filters, HtmlHelpers, and more. The utility of SpecsFor<Web> Helpers is easiest to see when you compare it to specs that *aren't* using them. Check out the examples below! [block:api-header] { "type": "basic", "title": "Testing a ViewResult" } [/block] Without SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "[Test]\npublic void then_it_says_hello_to_the_user()\n{\n var viewResult = _result.ShouldBeType<ViewResult>();\n var model = viewResult.Model.ShouldBeType<SayHelloViewModel>();\n model.ShouldLookLike(new SayHelloViewModel\n {\n Name = \"John Doe\"\n });\n}", "language": "csharp" } ] } [/block] With SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "[Test]\npublic void then_it_says_hello_to_the_user()\n{\n _result.ShouldRenderDefaultView()\n .WithModelLike(new SayHelloViewModel\n {\n Name = \"John Doe\"\n });\n}", "language": "csharp" } ] } [/block] [block:api-header] { "type": "basic", "title": "Testing a RedirectResult" } [/block] Without SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "[Test]\npublic void then_it_redirects_to_the_say_hello_action()\n{\n var redirectResult = _result.ShouldBeType<RedirectToRouteResult>();\n redirectResult.RouteValues[\"controller\"].ShouldEqual(\"Home\");\n redirectResult.RouteValues[\"action\"].ShouldEqual(\"SayHello\");\n redirectResult.RouteValues[\"name\"].ShouldEqual(\"Jane Doe\");\n}", "language": "csharp" } ] } [/block] With SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "[Test]\npublic void then_it_redirects_to_the_say_hello_action()\n{\n _result.ShouldRedirectTo<HomeController>(\n c => c.SayHello(\"Jane Doe\"));\n}", "language": "csharp" } ] } [/block] [block:api-header] { "type": "basic", "title": "Testing an Action Filter" } [/block] Without SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "protected override void When()\n{\n var httpContext = new Mock<HttpContextBase>().Object;\n var controllerContext = new ControllerContext(httpContext, new RouteData(), new Mock<ControllerBase>().Object);\n var reflectedActionDescriptor = new ReflectedActionDescriptor(typeof(ControllerBase).GetMethods()[0], \"Test\", new ReflectedControllerDescriptor(typeof(ControllerBase)));\n _filterContext = new ActionExecutingContext(controllerContext, reflectedActionDescriptor, new Dictionary<string, object>());\n SUT.OnActionExecuting(_filterContext);\n}", "language": "csharp" } ] } [/block] With SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "protected override void When()\n{\n _filterContext = new FakeActionExecutingContext();\n SUT.OnActionExecuting(_filterContext);\n}", "language": "csharp" } ] } [/block] [block:api-header] { "type": "basic", "title": "Testing an HtmlHelper" } [/block] Without SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "public class when_creating_a_bootstrap_button : SpecsFor<HtmlHelper>\n{\n private HtmlTag _button;\n\n protected override void InitializeClassUnderTest()\n {\n var contextMock = new Mock<HttpContextBase>();\n contextMock.Setup(x => x.Request).Returns(new Mock<HttpRequestBase>().Object);\n var response = new Mock<HttpResponseBase>();\n response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(s => s);\n contextMock.Setup(x => x.Response).Returns(response.Object);\n var viewContext = new ViewContext()\n {\n HttpContext = contextMock.Object\n };\n var viewDataContainer = new Mock<IViewDataContainer>().Object;\n SUT = new HtmlHelper(viewContext, viewDataContainer);\n }\n\n protected override void When()\n {\n _button = SUT.BootstrapButton(\"Submit!\");\n }\n\n [Test]\n public void then_it_creates_submit_button()\n {\n _button.Attr(\"type\").ShouldEqual(\"submit\");\n }\n\n [Test]\n public void then_it_sets_the_correct_button_classes()\n {\n _button.HasClass(\"btn\").ShouldBeTrue();\n _button.HasClass(\"btn-primary\").ShouldBeTrue();\n }\n}\n", "language": "csharp" } ] } [/block] With SpecsFor<Web> Helpers: [block:code] { "codes": [ { "code": "public class when_creating_a_bootstrap_button : SpecsFor<FakeHtmlHelper>\n{\n private HtmlTag _button;\n\n protected override void When()\n {\n _button = SUT.BootstrapButton(\"Submit!\");\n }\n\n [Test]\n public void then_it_creates_submit_button()\n {\n _button.Attr(\"type\").ShouldEqual(\"submit\");\n }\n\n [Test]\n public void then_it_sets_the_correct_button_classes()\n {\n _button.HasClass(\"btn\").ShouldBeTrue();\n _button.HasClass(\"btn-primary\").ShouldBeTrue();\n }\n}", "language": "csharp" } ] } [/block] [block:api-header] { "type": "basic", "title": "There's more..." } [/block] SpecsFor<Web> Helpers includes a slew of fake objects you can use, many of which can be configured using SpecsFor's GetMockFor method (even though they aren't actually mock objects!) Here's a full list of the available fake objects and their corresponding GetMockFor-compatible configuration interface (where applicable): * FakeActionExecutingContext * FakeHtmlHelper * FakeHttpContext * IFormParamsProvider * IHttpContextBehavior * IQueryStringParamsProvider * IServerVariablesParamsProvider * IHeadersParamsProvider * FakeHttpRequest * ICookieProvider * IFormParamsProvider * IQueryStringParamsProvider * IServerVariablesParamsProvider * IHeadersParamsProvider * FakeHttpSessionState * FakeIdentity * FakePrincipal * FakeRequestContext * FakeUrlHelper * FakeViewContext * FakeViewDataContainer In many cases, you can use the fake objects as-is in your specs. If you need to configure the behavior of a fake, such as wiring up query string parameters when you're using a FakeHtmlHelper, you can grab the behavior interface using GetMockFor, then configure the behavior that the fake will use: [block:code] { "codes": [ { "code": "public class when_getting_the_app_version_and_the_app_is_in_debug_mode : SpecsFor<FakeHtmlHelper>\n{\n private string _version;\n\n protected override void Given()\n {\n GetMockFor<IHttpContextBehavior>()\n .Setup(x => x.IsDebuggingEnabled)\n .Returns(true);\n }\n\n protected override void When()\n {\n _version = SUT.GetVersionString();\n }\n\n [Test]\n public void then_the_version_contains_the_debug_suffix()\n {\n _version.EndsWith(\"DEBUG\").ShouldBeTrue();\n }\n}", "language": "csharp" } ] } [/block]