Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameters to TestDelegate in NUnit

I am trying to create a method that takes a testdelegate or delegate and passes parameters to the delegate object. This is because I am creating a test for a methods in controllers that all takes the same parameter (an id), and i do not want to create a test for all of the controller methods.

Code I have:

protected void AssertThrows_NullReference_Og_InvalidOperation(TestDelegate delegateMethod)
{

    Assert.Throws<NullReferenceException>(delegateMethod);
    Assert.Throws<InvalidOperationException>(delegateMethod);
    Assert.Throws<InvalidOperationException>(delegateMethod);
} 

What i would like to do:

protected void AssertThrows_NullReference_Og_InvalidOperation(TestDelegate delegateMethod)
{

    Assert.Throws<NullReferenceException>(delegateMethod(null));
    Assert.Throws<InvalidOperationException>(delegateMethod(string.Empty));
    Assert.Throws<InvalidOperationException>(delegateMethod(" "));
} 

EDIT: I forgot to mention that the controller has a return value. Therefore Action cannot be used.

like image 594
Stian Standahl Avatar asked Jan 02 '13 09:01

Stian Standahl


People also ask

How do I catch exceptions in NUnit?

Throws( Is. InstanceOf<ApplicationException>(), code ); // Allow both ApplicationException and any derived type Assert. Catch<ApplicationException>( code ); // Allow any kind of exception Assert. Catch( code );

What is TestDelegate?

In the above code TestDelegate is a delegate of the form void TestDelegate(), which is used to execute the code in question. Under . NET 2.0, this may be an anonymous delegate. If compiling under C# 3.0, it may be a lambda expression. The following example shows different ways of writing the same test.


2 Answers

Use Action<string> to pass method which accepts single string parameter. Invoke that action with your test parameters:

protected void AssertThrowsNullReferenceOrInvalidOperation(Action<string> action)
{
    Assert.Throws<NullReferenceException>(() => action(null));
    Assert.Throws<InvalidOperationException>(() => action(String.Empty));
    Assert.Throws<InvalidOperationException>(() => action(" "));
}

Usage:

[Test]
public void Test1()
{
    var controller = new FooController();
    AssertThrowsNullReferenceOrInvalidOperation(controller.ActionName);
}

UPDATE:

Use Func<string, ActionResult> for controllers which returns ActionResult. Also you can create generic method for that purpose.

like image 73
Sergey Berezovskiy Avatar answered Oct 08 '22 08:10

Sergey Berezovskiy


As said in the edit, the controller has a return type. Therefore, I had to change from Action to Func, and since i used it in a unit test i had to create a temporary object that holds the function.

Based on lazyberezovsky's answer here is my resulting code:

    public class BaseClass
    {
            protected Func<string, ActionResult> tempFunction;
            public virtual void AssertThrowsNullReferenceOrInvalidOperation()
            {
                if (tempFunction != null)
                {
                    Assert.Throws<NullReferenceException>(() => tempFunction(null));
                    Assert.Throws<InvalidOperationException>(() => tempFunction(string.Empty));
                    Assert.Throws<InvalidOperationException>(() => tempFunction(" "));
                }
            }
    }

The unit test is then:

[TestFixture]
public class TestClass
{
        [Test]
        public override void AssertThrowsNullReferenceOrInvalidOperation()
        {
            tempFunction = Controller.TestMethod;
            base.AssertThrowsNullReferenceOrInvalidOperation();
        }
}
like image 45
Stian Standahl Avatar answered Oct 08 '22 07:10

Stian Standahl