views:

266

answers:

2

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?

A: 

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.

eglasius
Not really, I developed the control doing simple TDD but am finding that my tests do not cover the scenario where the control is rebuilt during postback which is exactly when it breaks. There is very little code in my class to extract, I just need coverage for that simple scenario.
George Mauer
I guess the problem ultimately is that I don't know how to TDD my way through the postback scenario. WatiN is a solution but that seems like complete overkill
George Mauer
@George check my update. Note that what I said regarding the asp.net page lifecycle still applies, so you need to look close into the lifecycle and how it can affect your custom control's code.
eglasius
+1  A: 

"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.

D. P. Bullington
I suppose so, what I'm looking for is more in the vein of "the framework rebuilds the control in this simple manner and passing it the viewstate, just do that". I'm hearing its not that simple...
George Mauer