I'm implementing the Data Validation Validators as shown here:
http://www.asp.net/learn/mvc/tutorial-39-cs.aspx
This works great at runtime, but how can I Unit Test to verify if I say attribute [StringLength(10)], an error is returned?
Brad Wilson describes it pretty well in a blog post from a while ago (you'll have to scroll down a bit). Basically, you write tests where you use reflection to make sure that the proper attributes are applied, and then trust the framework to do its job on adding errors. After all, someone else tested the Data Annotation Validators before they were published - you just have to make sure you use them right =)
This post by Villecoder is the unit testing solution I'm using. It also allows you unit unit test custom annotations
http://villecoder.com/2010/04/23/unit-testing-custom-data-annotations/
Related
I would like to work on a replacement for the various strongly-typed Asp.Net Html-extension methods such as TextBoxFor()
As soon as I started off, I realized that I need to account for the behavior of these methods with respect to model validation. I though "OK, I'll grab the list of class-names applied in various validation contexts from the documentation", but when I look up TextBoxFor on MSDN, there is absolutely no mention of this functionality.
I could just figure it out in the case of model-validation, though I'm not 100% confident that I know all the cases these methods are designed to handle. And it occurs to me that there might be other functionality provided by these extensions that I am not aware of. Googling has resulting in many "how-tos" for the basics of using these methods, but nothing even close to comprehensive.
Question: What is, or where can I find a comprehensive listing of the functionality of these methods? I'm not just looking for method signatures and return-types here. I need a full documentation of functionality that I could use to write a test suite against.
As far as documentation is concerned, MSDN is the best resource you could hope to get. It might not be enough for you, but that's the reality you need to face.
Personally I use the ASP.NET MVC source code (which is available for download) and look through it to better understand how those helpers are implemented and how they work.
But since you have mentioned something about model validation in your question, you'd better look at the ValidationMessageFor and ValidationSummary helpers instead of the TextBoxFor helper. The only place where some validation is done in the TextBoxFor helper is to check whether there are validation errors for the corresponding model property in order to add the validation error CSS class to the input field.
I am writing some BDD style Spec Flow test which is working out smoothly! Now, I am in a position to test that the data annotations validations are fired. I am thinking that this test should be performed by using WatiN tool since the UpdateModel is fired when the values from the form are posted.
How do you test that the validations are firing?
There are a number of ways you can do this. You dont have to use WatiN to check validations, I am using SpecFlow to call controller methods and then interrogate the ModelState property checking for the errors I expected to be raised from the invalid data I entered.
You can also use WatiN to check that particular error text is displayed on screen by attatching to the browser and using the Find.ByText("Error Message") method.
If you haven't already I strongly suggest having a read of this article, helped me alot when starting out with SpecFlow/WatiN and BDD:
http://msdn.microsoft.com/en-us/magazine/gg490346.aspx
Hope that helps.
By testing them with invalid data...(and valid data)
If your model has an annotate just fire values at it you may write a scenario like
Scenario: Adding an invalid user
GIVEN I am in the add user page
AND I have not filled in the name
WHEN I Add
THEN I should see the error defined in my annotation
more on testing annotations is here http://bradwilson.typepad.com/blog/2009/04/dataannotations-and-aspnet-mvc.html
but you just want them to fire. Remember you are testing from the outside in this case.
I'm thinking of two options right now for model-base validation for an ASP.net project I'm starting:
xVal (Steve Sanderson's project) and the Enterprise module that Stephen Walther uses on this page
I don't really know enough to talk about the preferences as I haven't used either of them yet. Any ideas?
Update Using LinqToSql for ORM right now, but am open to changes.
One difference I see in reviewing the two is that Stephen Walther's blog post describes a library which does only validation in the Web server, where as xVal works with jQuery validators to do in-browser validation, as well. This feature, incidentally, is almost completely automatic.
FluentValidation is nice. NHibernate also has built in model validation. Then you need something like Scott Guthrie's technique for binding errors to the UI.
I've been using xVal to and i have integrated it into the IDataErrorInfo interface introduced into MVC RC1. I like it.
Here is a post I wrote which explains a few things.
http://schotime.net/blog/index.php/2009/03/05/validation-with-aspnet-mvc-xval-idataerrorinfo/
Hope this helps.
Shamelessly promote my validation library. Built for jQuery validate & Enterprise Library and work out of the box for just that. That said, functionality and code are simple enough to modify/extend if you want.
You could also check out this new technique on LosTechies http://www.lostechies.com/blogs/hex/archive/2009/06/10/opinionated-input-builders-for-asp-net-mvc-part-5-the-required-input.aspx I like the fact that you inputs are setup globaly which is really DRY. Also you could just skip the client side validation and do an jquery ajax submit form to the server, which performs validation model and business logic all in one place, which is also DRY :) Also it means you will get the product out the door quicker and you can add client side validation later as a bonus or to progressively enhance the forms.
Another vote for xVal. It's real sweet. I like using Buddy Classes and DataAnnotations to do the validation lifting. Outside of making things work with Linq2Sql as you cannot add attributes to your fields, buddy classes give one a bit of flexibility to have multiple models share the same validation info. Comes in real handy for those ModelEditData classes that seem to always become neccessary.
Are you using an ORM? If so, which one are you using? I've had a lot of luck, when using Castle ActiveRecord, simply sticking with their default model-level validation. If you're not using that, though, this is probably not too helpful. :-)
Most of the stackoverflow posts about ASP.NET MVC unit testing talk about a specific issue or specific thing to test such as testing HtmlHelpers. Others on the subject of best practices have surprisingly few answers. Available videos I have watched are completely useless in my opinion - and mind blowingly long (by the time you've watched 1.5 hours and not learned anything).
What I want to know from people who've actually been doing this is :
What are the most important things to test first
What doesn't need testing (shock horror for me saying that but I'm not after 100%)
What is hard to test and how have you overcome difficult thins to test.
What things can break in refactoring that a test won't catch.
I'm not new to how to unit test - but I'm very new to actually doing it consistently. I'd really appreciate lessons learned from those who are experts in unit testing ASP.NET MVC.
I'm really looking for specific things you might only find out after having tried it - not jsut general advice like 'use interfaces' - although of course any suggestions are welcome.
Oh and lets say I've decided to use Microsoft's unit testing - just becasue its already there. I think all answers would apply to all testing frameworks though.
Test your routing. You should use RouteLink to remove ambiguity when you generate a URL in your View, but when you submit a URL, you are dependent upon the routing system to select the correct route. So test that the URL patterns you support do in fact return the correct route.
Test your controller actions. Use a mock repository, and test that manually invoking each action has the results you expect.
Test all business logic in your model. This is obvious, and little different from non-MVC applications.
Test any custom view helpers you write. Although I don't generally unit test views, view helpers are different.
Test your JavaScript. There are unit testing frameworks for this, that testing JavaScript is so easy that such frameworks are hardly necessary. But testing JavaScript is incredibly important, due to the tendency of the language to hide errors from you.
If you have written any custom model binders, they need special attention. For one thing, it is a lot easier to debug a model binder via a unit test than when it is "live" in the application.
I'd like to elaborate on testing controller actions:
Verify you get the proper ActionResult. A redirect is different from a view.
Also verify the expected view name. If you rely on the default view, it should be empty.
Verify you get the proper view model.
Verify all branches in your action. Keep them to a minimum and move them to a helper / service when they grow too many.
In short, verify anything from the ActionResult that you will use.
I dont think the answer has to be specific to ASP.NET MVC.
Like any other application, the most important thing you have to test is your core logic.
That is, your model code and your controller actions.
If all the business logic is present in a datamodule (TSQLDataSets and TDataSetProviders) how would you refactor the code to make the application more appropiate for unit testing?
After the last question about this, I wrote a blog post about how to do it.
Some basic tips:
Your DataModules should never have any references to forms or any other UI components
Put the TDataSources on forms and not in your DataModules.
Make sure there isn't any prompts for confirmation and operations that requires user input on DataModules code.
You should not use any global vars.
Hope this helps.
For automated construction of tests for DUnit, you could use OpenCTF, which is able to find all components and create test cases automatically at test run time. The example tests include some basic data access layer tests.
http://sourceforge.net/projects/openctf/
and
http://cc.embarcadero.com/Item/24136
alt text http://www.mikejustin.com/images/OpenCTF.gif