How to unit test for turning off request validation? - asp.net

I'm new at this TDD thing but making a serious effort, so I'm hoping to get some feedback here.
I created a little web service to minify JavaScript, and everything was nice, with all my tests passing. Then I noticed a bug: if I tried to minify alert('<script>');, it would throw a HttpRequestValidationException.
So that's easy enough to fix. I'll just add [AllowHtml] to my controller. But what would be a good way to unit test that this doesn't happen in the future?
The following was my first thought:
[TestMethod]
public void Minify_DoesntChokeOnHtml()
{
try
{
using (var controller = ServiceLocator.Current.GetInstance<MinifyController>())
{
return controller.Minify("alert('<script></script>');");
}
}
catch (HttpRequestValidationException)
{
Assert.Fail("Request validation prevented HTML from existing inside the JavaScript.");
}
}
However, this doesn't work since I am just getting a controller instance and running methods on it, instead of firing up the whole ASP.NET pipeline.
What would be a good unit test for this? Maybe reflector on the controller method to see if the [AllowHtml] attribute is present? That seems very structural, and unlikely to survive a refactoring; something functional might make more sense. Any ideas?

You have only two options:
First
Write integration test that hosts MVC in-proc or runs using browser (using Watin for instance) that will cover you scenario.
Second
Write unit test that will check that method is marked with needed attribute.
I would go with the first option.

Related

Strongly-Typed Route Testing

If I understand the example correctly, MvcContrib TestHelper has a strongly-typed test of a route mapping to a particular controller. The down-side is that again, if I understand the example, the route being tested does not come from the global.asax file; It instead comes from the test setup.
In contrast, the book "Pro ASP.NET MVC3 Framework" shares route-test helpers that actually do leverage the routes in the global.asax file. These helpers, however, are not strong typed (or even loose-typed) to a particular controller:
[TestMethod] //sample from the book...
public void TestIncomingRoutes() {     
// check for the URL that we hope to receive     
TestRouteMatch("~/Admin/Index", "Admin", "Index");
}
I'd like to have the best of both worlds. Has anyone a link to helper code that (1) expressly identifies a particular controller, (2) uses the routes in the global.asax for the tests and (3) is not married to Rhino Mocks - as I prefer MOQ.
Thanks.
It seems like you want to test your HttpApplication subclass (global.asax.cs code) to ensure it calls the code to register the routes. I'm not sure that's really necessary, as it will be pretty apparent that nothing works if you fail to do so. OTOH, the MvcContrib is allowing you to test that the URLs you want actually map to something, which has a lot of value if you've carefully designed your urls to be SEO friendly. That is worth testing, IMO.

Controller.User is Null During Unit Test

I have the following code in my controller action method:
if (User.Identity.IsAuthenticated)
{
// ...
}
It seems to work fine. But when I run a unit test that calls this action, it fails because User is null?
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?
You probably need to set the User property as part of your setup. You would do this by mocking the HttpContextBase via ControllerContext used to create the controller so that it returns your mocked user. Set your mocked ControllerContext into the ControllerContext property, and it will find User provided you've configured the object graph correctly.
The User property of the Controller class is copied from the current HttpContext - you have to provide a context and set the User there appropriately for this to work in your unit tests.
User will be null if you run the code outside of the context of a web request. It sounds like you're running tests on your methods directly.
You have two options.
The quickest fix to your problem, but not necessarily the most sustainable fix, would be to simply call your running website from your unit test as a WebRequest.
The more sustainable fix would be to gather your uses of context-dependent server-side functionality (such as User) into a single class that you can mock/fake.
Edit
Can anyone suggest the best way to deal with this? Do I have to restructure this code just for unit tests?
The bottom line answer is "yes". More importantly, you probably want to, because it will make your system more flexible and/or maintainable in the long run.

Refactoring session variables

I'm visiting an app that's been in use for the past 2+ years and it is in desperate need of refactoring. It is of my own work, but you know what it's like when you visit old code again.
Anyway I've been using the excellent advice at sourcemaking to refactor and the code is already looking much better.
The problem now is there are loads of Session["variable"] sprinkled throughout the code, so what's the most accepted way to refactor these out? I found this article at code project but apparently it can be quite dangerous.
The best way to refactor random session usage like this is to create a static SessionWrapper with static properties that encapsulate the ASP.NET session store:
static class SessionWrapper
{
public static string Variable
{
get { return Session["variable"]; }
set { Session["variable"] = value; }
}
}
This will also allow you to put some logic around the getting and setting of these values and keep them in a centralized place.
I would also strongly recommend that you have some integration tests in place before you start this process so that you can be sure you haven't missed anything.

Setting up functional Tests in Flex

I'm setting up a functional test suite for an application that loads an external configuration file. Right now, I'm using flexunit's addAsync function to load it and then again to test if the contents point to services that exist and can be accessed.
The trouble with this is that having this kind of two (or more) stage method means that I'm running all of my tests in the context of one test with dozens of asserts, which seems like a kind of degenerate way to use the framework, and makes bugs harder to find. Is there a way to have something like an asynchronous setup? Is there another testing framework that handles this better?
It is pretty easy, but took me 2 days to figure it out.
The solution:
First you need to create a static var somewhere.
public static var stage:Stage
There is a FlexUnitApplication.as created by the flexunit framework, and at the onCreationComplete() function, you can set the stage to the static reference created previously:
private function onCreationComplete():void
{
var testRunner:FlexUnitTestRunnerUIAS=new FlexUnitTestRunnerUIAS();
testRunner.portNumber=8765;
this.addChild(testRunner);
testStageRef.stage=stage //***this is what I've added
testRunner.runWithFlexUnit4Runner(currentRunTestSuite(), "testsuitename");
}
and when you would access the stage in the program, you should replace it to:
if(stage==null) stage=testStageRef.stage
Assuming you're using FlexUnit 4, addAsync can be called from a [BeforeClass] method:
public class TestFixture
{
[BeforeClass]
public static function fixtureSetup() : void
{
// This static method will be called once for all the tests
// You can also use addAsync in here if your setup is asynchronous
// Any shared state should be stored in static members
}
[Test]
public function particular_value_is_configured() : void
{
// Shared state can be accessed from any test
Assert.assertEquals(staticMember.particularValue, "value");
}
}
Having said that, testing code that accesses a file is really an integration test. I'm also hardly in a position to argue against using ASMock :)
Sounds like you need to remove the dependency of loading that external file. Pretty much all Aysnchronous tests can be removed through the use of a mocking frameworks. ASMock is an awesome choice for Flex. It will allow you to fake the URLoader object and return faked configurations to run your tests against. Mocking will help with you write much better unit tests as you can mock all dependencies synchronous or asynchronous.

How to unit test server controls on postback?

I am trying to create my own EasyBinderDropDown that currently looks like this:
public class EasyBinderDropDown : DropDownList, ICanBindToObjectsKeyValuePair {
public void BindToProperties<TYPE_TO_BIND_TO>(IEnumerable<TYPE_TO_BIND_TO>
bindableEnumerable,
Expression<Func<TYPE_TO_BIND_TO, object>> textProperty,
Expression<Func<TYPE_TO_BIND_TO, object>> valueProperty) {...}
public bool ShowSelectionPrompt { get; set; }
public string SelectionPromptText { get; set; }
public string SelectionPromptValue { get; set; }
//...
}
Basically it is very helpful for easy binding to objects from inside code since you just do something like _dropDown.BindToProperties(myCustomers, c=>c.Name, c=>c.Id) and it works for you, also by setting ShowSelectionPrompt and SelectionPromptText I can easily have a "Select Customer" Line. I don't want to ask so much about my specific implementation, rather I am confused how to write unit tests for some scenarios.
For example my current tests cover the control being created properly during load and having its output render properly but I am lost as to how to test what happens when the control gets posted back. Can anyone give me some advice on how to test that? I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt?
"I would prefer to do this without having to mock an HTTPContext or anything like that, Is there a way I can simulate the control being rebuilt."
By definition, you are not asking to "unit test"; you are looking for an "integration test". If you are not mocking the major dependencies, in this case, the ASP.NET runtime components, the what you are testing is the integration between your control and ASP.NET.
If you do not want to mock out the HttpContext and friends, then I would suggest an automated web testing framework such as Selenium or NUnitAsp.
Update: Based on the comment. Don't have the code access directly the IsPostback or other asp.net stuff. Wrap them with simple classes/interfaces. Once you have done that, send mocks that implement those interfaces. This way you don't have to mock the whole HttpContext, just the pieces that matter for the code (which are really clear based on the interfaces involved).
Also, given it is an asp.net custom control, you don't want to force requirements on external things like dependency injection. Have a default (no parameters) constructor, that sets up the control to use the asp.net stuff. Use a constructor with more parameters to send the mocked versions.
Initial answer:
It seems to me you are looking for a happy middle between unit tests and integration tests. You are working with a custom control, which can go wrong on different parts of the asp.net's page lifecycle.
I would:
Check if you can move parts of the code
out of the custom control to separate
classes, you can more easily unit test
For simple scenarios, rely on the functional tests of the rest of the project to catch any further issue with the control (use watin / selenium rc).
For more complex scenarios, as if the control will be used in different parallel projects or will be delivered to the public, set up some test pages and automate against it (again watin / selenium rc).
You write the tests in watin / selenium rc in c#, and run them in your "unit" test framework. Make sure to keep them separated from the unit tests, since they will clearly run slower.
Ps. I haven't used ms test support for asp.net, it might have some support for what you are looking for.

Resources