ASP.NET MVC Tip #28 – Test If Caching Is Enabled

In this tip, I demonstrate how you can test if the OutputCache attribute is present on a controller action. I also demonstrate how you can test if the OutputCache attribute is set with a particular duration.

Caching is the most effective way to improve the performance of an ASP.NET MVC application. The slowest operation that you can perform in a web application is database access. The best way to improve database access performance is to not access the database at all. Caching enables you to avoid having to access the database with each and every request.

You can cache the view (or any Action Result) returned by a controller action by adding an OutputCache attribute to the controller action. For example, the controller in Listing 1 is configured to cache the view returned by the Index() action for 10 seconds.

Listing 1 – HomeController.vb (VB.NET)

<HandleError()> _
Public Class HomeController
    Inherits System.Web.Mvc.Controller

    <OutputCache(Duration:=10)> _
    Function Index()
        Return View()
    End Function

End Class

Listing 1 – HomeController.cs (C#)

using System.Web.Mvc;

namespace Tip27.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        [OutputCache(Duration=10)]
        public ActionResult Index()
        {
            return View();
        }

    }
}

The Index() action in Listing 1 returns the view in Listing 2. Notice that this view simply displays the current time (see Figure 1).

Figure 1 – A view cached for 10 seconds

image

Listing 2 – Index.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Tip27.Views.Home.Index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <div>

    The current time is: <%= DateTime.Now.ToString("T") %>


    </div>
</body>
</html>

(By the way, don’t ever set the OutputCache attribute in the view itself. You should only configure caching within a controller).

If you invoke the Index() action, then you get the Index view. If you repeatedly hit refresh in your browser, then the time displayed in the view updates once every 10 seconds.

So, how do you test caching? I don’t mean how do you test whether caching works or not. This is a framework issue that Microsoft has tested for you. I mean how do you test whether or not caching is enabled on a particular controller action in an MVC application that you write?

It turns out that testing whether a particular controller action has an OutputCache attribute is really easy. Take a look at the test in Listing 3.

Listing 3 – HomeControllerTest.vb (VB.NET)

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Web.Mvc
Imports Microsoft.VisualStudio.TestTools.UnitTesting
Imports Tip28

<TestClass()> Public Class HomeControllerTest


    <TestMethod()> Public Sub IndexIsCachedFor10Seconds()
        ' Arrange
        Dim indexMethod = GetType(HomeController).GetMethod("Index")
        Dim outputCacheAttributes = indexMethod.GetCustomAttributes(GetType(OutputCacheAttribute), True)

        ' Assert
        Assert.IsTrue(outputCacheAttributes.Length > 0)
        For Each outputCache As OutputCacheAttribute In outputCacheAttributes
            Assert.IsTrue(outputCache.Duration = 10)
        Next
    End Sub


End Class

Listing 3 – HomeControllerTest.cs (C#)

using System.Reflection;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tip27.Controllers;

namespace Tip27Tests.Controllers
{
    /// <summary>
    /// Summary description for HomeControllerTest
    /// </summary>
    [TestClass]
    public class HomeControllerTest
    {
        [TestMethod]
        public void IndexIsCachedFor10Seconds()
        {
            // Arrange
            MethodInfo indexMethod = typeof(HomeController).GetMethod("Index");
            var outputCacheAttributes = indexMethod.GetCustomAttributes(typeof(OutputCacheAttribute), true);

            // Assert
            Assert.IsTrue(outputCacheAttributes.Length > 0);
            foreach (OutputCacheAttribute outputCache in outputCacheAttributes)
            {
                Assert.IsTrue(outputCache.Duration == 10);
            }
        }


    }
}

The test in Listing 3 grabs all of the OutputCache attributes from the Index method (there might be more than one). If the Index() method does not include at least one OutputCache attribute then the test fails. If each of the OutputCache attributes does not have a Duration property set to the value 10 seconds, then the test fails.

Discussion

  1. jdelator says:

    This probably isn’t the place to ask this but is there a way in either this release or in a future release so that when the view is cached there is a substitution that replaces dynamic data (such as a user’s name?)

    Like in this example?

    blog.maartenballiauw.be/…/…g-substitution.aspx

  2. http:// says:

    Yea, about those … Can we stop’em?

  3. turkie says:

    Yea, about those … Can we stop’em?

  4. http:// says:

    How can you cache data in MVC? e.g If a cached version of a returned object through say LINQ to SQL is current I want to use that and not have to query the database again. In traditional ASp.NET apps (webforms) we can use the page’s cache properties to store data. I can’t see where this would be done within MVC, I assume a cache at the controller level is needed?.

  5. Jack says:

    HttpRuntime.Cache is perfect, it works during the test project(unit test)!

  6. MOV to DVD says:

    This is a pretty useful tool. It needs a little tweaking, but I like this better than my NAnt solution I did recently.

  7. he __proto__ feature creates a security breach. I’ve filed a bug report

  8. fer tI tried to mock a call to a Linq to SQL query, but I am struggling.

  9. Thanks Good Share very Mach

  10. seo india says:

    Thanks for sharing such a useful info.

  11. education says:

    Thanks again for another great post.

  12. seo says:

    Would be great for this project as well.

  13. business says:

    really interesting information. Thanks for the reference to it.

  14. gifts says:

    Dear Great post.

  15. vacation says:

    so thanks a lot.

  16. health says:

    Great information, though – thanks.

  17. Murat says:

    thanks very mach good share…

  18. very nice post thanks!!!

    i really like it

  19. i have downloaded the “LatestVersion.zip” and right click on it and select the properties but the “unblock” button is not in display ! what to do further ??

  20. It is often seen that some people start smoking to get relieved from the stress. They start using it for several occasions and soon they get trapped into its addiction

  21. What if I set the OutputCache attribute in the view itself?

  22. Online Generic Viagra resource containing quality information on Erectile Dysfunction, Impotence, Viagra News, Viagra Usage, Viagra Forum etc to help you understand the most effective treatment available for Erectile Dysfunction(Impotence)

  23. Be Creative says:

    iteresting post.. thanks!!!

  24. very nice post thanks!! i really like it.

  25. Our website have many goods,Replica Rolex
    Vertu
    Vertu Replica,
    Replica handbags,
    Rolex,
    Replica Watches I belive that you will like them!052

  26. Stephen your posts are always useful. Thanks for sharing.

  27. Infections says:

    Thanks and excellent post!!!

  28. Mature Male says:

    cool this blog is great very good

  29. Hi
    Great content about Test If Caching Is Enabled congratulations.

  30. Helloooo
    Great post Stephen ! Your are the best ! Thanks.

  31. Hello

    I have enjoyed following your blog entries.

  32. Thanks and excellent post again Stephen!!!

  33. Hello
    Thanks the information is excellent and for sharing a informative
    Good day.

  34. hello

    Hi
    Very good post, helped me a lot!.
    Congratulations.

  35. get and keep an erection satisfactory for sexual activity.

  36. Hello
    i`m real impressed with this blog is awesome, i want to learn more

  37. This was so difficult to me. I did not understand it so well.

  38. Hello
    Great post thanks for sharing a informative article keep it up
    Good Day!!

  39. 4544554 It looks like DataContextExtensions.cs line 45 of the Save method should pass the primaryKeyName through to Update.

  40. I like your post is very professional.

  41. Hello friends I am very grateful to your service by posting on this topic

  42. HD Video Converter says:

    As the users of HD Camcorders like Sony, Canon, Panasonic, this HD Converter is necessary to help us convert hd Video easily and quickly. The Converter for HD provides several practical editing functions to help you achieve ideal output effect. Trim function is to cut videos into clips which you can just convert and transfer to your player. Crop function helps you remove black bars around the movie. You could use Effect function to adjust video brightness, contrast, saturation and more parameters. More powerful and considerate functions are waiting for you to explore.MKV Converter l FLV Converter l DVD Ripper !