MY TESTED ASP.NET CORE MVC DOCS
  • Attributes
Show / Hide Table of Contents
  • Introduction
  • Getting Started
  • Packages
  • Debugging Failed Tests
  • Controllers
  • Models
  • Database
  • Services
  • HTTP & Authentication
  • Licensing
  • Attributes
  • Exceptions
  • Options
  • Session & Cache
  • ViewBag, ViewData & TempData
  • View Components
  • Routing
  • Various Helpers
  • Organizing Tests
  • Test Configuration
  • Extension Methods

Attributes

This section will cover testing of attributes and their properties.

Controller attributes

First, we need another package. Again?!

Do not worry, later in this tutorial we are going to use the "Universe" package and this madness will end. The purpose here is to show you the different components of the testing framework.

Now, obey the rules and add "MyTested.AspNetCore.Mvc.Controllers.Attributes" to your "MusicStore.Test.csproj" project:

<!-- Other ItemGroups -->

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
    <PackageReference Include="Moq" Version="4.13.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Authentication" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Controllers" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Controllers.ActionResults" Version="2.2.0" />
    <!-- MyTested.AspNetCore.Mvc.Controllers.Attributes package -->
    <PackageReference Include="MyTested.AspNetCore.Mvc.Controllers.Attributes" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Controllers.Views" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Controllers.Views.ActionResults" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.DependencyInjection" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.EntityFrameworkCore" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Http" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.Models" Version="2.2.0" />
    <PackageReference Include="MyTested.AspNetCore.Mvc.ModelState" Version="2.2.0" />
    <PackageReference Include="xunit" Version="2.4.0" />
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
  </ItemGroup>

<!-- Other ItemGroups -->

Let's assert that our "CheckoutController" is decorated with the commonly used "AuthorizeAttribute". Go to the CheckoutControllerTest" class and add the following test:

[Fact]
public void CheckoutControllerShouldHaveAuthorizeAttribute()
    => MyController<CheckoutController>
        .Instance()
        .ShouldHave()
        .Attributes(attributes => attributes // <---
            .RestrictingForAuthorizedRequests());

Simple as that. Additionally, in the the "HomeControllerTest" class, we can add:

[Fact]
public void HomeControllerShouldHaveNoAttributes()
    => MyController<HomeController>
        .Instance()
        .ShouldHave()
        .NoAttributes();

Of course, if you change "NoAttributes" to "Attributes", you will receive an error:

When testing HomeController was expected to have at least 1 attribute, but in fact none was found.

Action attributes

Action attributes are not different. Let's test the "RemoveAlbumConfirmed" action in the "StoreManagerController":

[HttpPost, ActionName("RemoveAlbum")]
public async Task<IActionResult> RemoveAlbumConfirmed(
    [FromServices] IMemoryCache cache,
    int id,
    CancellationToken requestAborted)
{

// action code skipped for brevity

We need to test the "HttpPost" and "ActionName" attributes:

[Fact]
public void RemoveAlbumConfirmedShouldHaveCorrectAttributes()
    => MyController<StoreManagerController>
        .Instance()
        .Calling(c => c.RemoveAlbumConfirmed(
            With.No<IMemoryCache>(),
            With.No<int>(),
            With.No<CancellationToken>()))
        .ShouldHave()
        .ActionAttributes(attributes => attributes // <---
            .RestrictingForHttpMethod(HttpMethod.Post)
            .ChangingActionNameTo("RemoveAlbum"));

Working like a charm! :)

Custom attributes

Sometimes you will have custom attributes which are not available in the fluent testing API. For example, you may have noticed that there is no method to test the "ValidateAntiForgeryTokenAttribute"". Actually, it's in the "ViewFeatures" package, but you don't know that! :)

Let's see an example and test the HTTP Post "Login" action in the "AccountController". It has these three attributes - "HttpPost", "AllowAnonymous", "ValidateAntiForgeryToken". For the latter you can use the "ContainingAttributeOfType" method:

[Fact]
public void LoginShouldHaveCorrectAttributes()
    => MyController<AccountController>
        .Instance()
        .Calling(c => c.Login(
            With.Default<LoginViewModel>(),
            With.No<string>()))
        .ShouldHave()
        .ActionAttributes(attributes => attributes
            .RestrictingForHttpMethod(HttpMethod.Post)
            .AllowingAnonymousRequests()
            .ContainingAttributeOfType<ValidateAntiForgeryTokenAttribute>()); // <---

The action is still invoked in this test, so we need to provide a non-null value for the "LoginViewModel" parameter. A better approach for testing action attributes (without having to specify the parameters) will be available in the next major release of the library. :)

Sometimes you may want to test specific property values of the attribute. You can use the "PassingFor" method:

[Fact]
public void StoreManagerControllerShouldHaveCorrectAttributes()
    => MyController<StoreManagerController>
        .Instance()
        .ShouldHave()
        .Attributes(attributes => attributes
            .SpecifyingArea("Admin")
            .PassingFor<AuthorizeAttribute>(authorize => authorize // <---
                .Policy == "ManageStore"));

Section summary

We saw how easy it is to assert and validate all kinds of controller and action attributes. But enough about them - in the next section we will cover thrown Exceptions.

  • Improve this Doc
In This Article
  • Controller attributes
  • Action attributes
  • Custom attributes
  • Section summary
Back to top Copyright © 2015-2016 MyTestedASP.NET. All Rights Reserved. Generated by DocFX