Raj Aththanayake's Blog Raj Aththanayake's Blog | Unit Testing

Simple test helper - MVC Action has decorated with a certain attribute

4. December 2012

Below is a useful helper, which allows you to verify whether an Action is decorated with a certain attribute. This is very simple to implement, but you can use something like below.

 

Test helper

        public static class ActionAttributeTestHelper

         {

             public static bool DoesMethodActionContainAttribute<TController, TActionResult, TAttribute>(Expression<Func<TController, TActionResult>> mExpression)

             {

                 Expression<Func<TController, TActionResult>> methodExp = mExpression;

                 var methodCall = (MethodCallExpression)methodExp.Body;

                 var methodInfo = methodCall.Method;

                 return methodInfo.GetCustomAttributes(false).Any(a => a is TAttribute);

             }

        }

 

Controller

        public class SutController : Controller

        {

             [Authorize]

             public ActionResult ActionWithAttributeNoParameter()

             {

                 return View();

             }

 

             public ActionResult ActionWithNoAttribute()

            {

                return View();

            }

 

            [Authorize]

            public ActionResult ActionWithAttributeWithParamter(int i)

            {

                return View();

            }

 

            [Authorize]

            [HttpGet]

            [OutputCache]

            public ActionResult ActionWithMultipleAttributes()

            {

                return View();

            }

        }

 

Unit Tests:

         [TestClass]

         public class SutControllerTest

         {

             [TestMethod]

             public void ActionWithAttributeNoParameter_ReturnsTrue()

             {

                 // Arrange

                 var sut = new SutController();

 

               //Act

                var doesTheMethodContainAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, AuthorizeAttribute>((x) => sut.ActionWithAttributeNoParameter());

 

                //Assert

                Assert.IsTrue(doesTheMethodContainAttribute);

            }

 

 

            [TestMethod]

            public void ActionWithNoAttribute_ReturnsFalse()

            {

                // Arrange

               var sut = new SutController();

 

                //Act

                var doesTheMethodContainAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, AuthorizeAttribute>((x) => sut.ActionWithNoAttribute());

 

                //Assert

                Assert.IsFalse(doesTheMethodContainAttribute);

            }

 

 

            [TestMethod]

            public void ActionWithAttributeWithParamter_ReturnsTrue()

            {

                // Arrange

                int anyNumber = 7;

                var sut = new SutController();

 

                //Act

                var doesTheMethodContainAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, AuthorizeAttribute>((x) => sut.ActionWithAttributeWithParamter(anyNumber));

 

                //Assert

                Assert.IsTrue(doesTheMethodContainAttribute);

            }

 

 

            [TestMethod]

            public void ActionWithMultipleAttributes_ReturnsTrue()

            {

                // Arrange

                var sut = new SutController();

 

                //Act

                var doesTheMethodContainAuthAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, AuthorizeAttribute>((x) => sut.ActionWithMultipleAttributes());

                var doesTheMethodContainHttpGetAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, HttpGetAttribute>((x) => sut.ActionWithMultipleAttributes());

               var doesTheMethodContainOutputCacheAttribute = ActionAttributeTestHelper.DoesMethodActionContainAttribute<SutController, ActionResult, OutputCacheAttribute>((x) => sut.ActionWithMultipleAttributes());

 

                //Assert

                Assert.IsTrue(doesTheMethodContainAuthAttribute);

                Assert.IsTrue(doesTheMethodContainHttpGetAttribute);

                Assert.IsTrue(doesTheMethodContainOutputCacheAttribute);

            } 

 

Unit Testing

Setup on the same method using MOQ

18. October 2012

Someone asked me about this today and I thought of it is a useful tip to write a small post. See the below code. If you know how to setup the same method in such a way that it would not override during the test execution, you can stop reading the rest of the post. If not please see the below example.

    public class SomeClass
    {
        private readonly ISomeInterface _someInterface;

        public SomeClass(ISomeInterface someInterface){
            _someInterface = someInterface;
        }

        public string SomeMethod()
        {
            string str1 = "str1";
            string str2 = "str2";
            
           var r1 = _someInterface.DoSomething(str1, str2);
            var r2 = _someInterface.DoSomething(string.Empty, string.Empty);
            
            return "something";
        }
    }

Notice that the same method call twice with different parameters. In our Unit Test, if we were to stub these two methods, the second/last setup method overrides the first one. In other words both r1 and r2 has the value of “bar”. This is not what we expect as we want setup methods to behave differently and return different values for r1 and r2.

Couple of ways you can achieve this with Moq.

a. Using It.Is<T>

You can specify a predicate that matches a specified criteria.

 

[TestMethod]
public void TestMethod3()
{
       var stub = new Mock<ISomeInterface>();
        stub.Setup(x => x.DoSomething(It.Is<string>
                     (s => !string.IsNullOrEmpty(s)), It.Is<string>
                     (s => !string.IsNullOrEmpty(s)))).Returns("foo");
        stub.Setup(x => x.DoSomething(It.Is<string>
                     (s => string.IsNullOrEmpty(s)), It.Is<string>
                     (s => string.IsNullOrEmpty(s)))).Returns("bar");
            
        var sut = new SomeClass(stub.Object);
        var r = sut.SomeMethod();
     }

b. This is the one that I like most as it only needs one setup and slightly  quicker

  Provide the delegate on the “Returns” that match the criteria.

 

 [TestMethod]
 public void TestMethod2()
 {
       var stub = new Mock<ISomeInterface>();
       stub.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
                .Returns<string, string>((x, y) => {
                     if (x != string.Empty && y != string.Empty){ return "foo";}
                     if (x == string.Empty && y == string.Empty){ return "bar";}         
                     return string.Empty;
           });

       var sut = new SomeClass(stub.Object);

       var r = sut.SomeMethod();

   }

Unit Testing