SpecFlow and BDD in ASP.NET MVC Application - asp.net-mvc

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.

Related

How to do Specification Testing with ASP.NET MVC Error view

I'm doing BDD on an MVC3 project with SpecFlow. My current specification scenario says that:
Given a user is working on the system
When an error is raised
Then the user should be redirected to error page
And display a link to go back where he came from
How can I test a spec like this? I usually test the controller directly, however the Error view given by the standard MVC3 template has no controller, and no controller is used, because is redirected by the HandleError global filter.
In exceptional cases I use Watin to test that the behavior conforms to what the specification says, however to do that I need a view that raises an error, something that when everything is working i do not have.
Any ideas on testing scenarios like this?
I have a few thoughts on this scenario:
1.) "Given a user is working on the system" is a pretty vague step. What code would be found in the step definition? Unless you have a user class that has a WorkingOnSystem method, it might be worth taking this line out.
2.) Without having seen the rest of your code, I think the target of this feature should be the HandleError filter itself. By its very definition, you know that when it is invoked an error has occurred. All you need to do is instantiate the filter, call the appropriate method, and test the results.
Think about it this way: What does "When an error is raised" mean in your system? If your HandleError filter is not the place, then you probably don't have a place. In which case, you'll need to be more specific.
I think the awkwardness around this spec is due to ASP.Net MVC. When you're dealing with a framework of abstractions, you're sometimes left to "wrap" your specs around some part of it. We just can't go end-to-end easily when the parts of the application come from so many places.

What is the connection between validate() and hasErrors()

This question comes from the problem of another question of mine. In that question, I come across a situation that hasErrors() function doesn't work for non-persistent domain class, even after all the things I did following the instruction, part 7.5 .
Following Victor's way, I fixed the problem by calling validate(), but I don't understand why it works. The Grails documents seem to say nothing about you should call a validate() before hasErrors() function. How could this happen?
It does make sense to me that validate would need to be called before asking an object whether it hasErrors (or save for proper domain objects, which calls validate under the covers). Validate in this context means "check whether this object is valid and indicate any errors if not".
Alternatively the GORM implementation would have to call validate every time any change is made to an object, which to me would be less desirable behaviour, as it might involve lots of work being done often and unnecessarily (some of those constraints could involve a lot of work).
The beginning of section 7.2 states pretty clearly "To validate a domain class you can call the validate method on any instance". It also states that "within Grails there are essentially 2 phases of validation, the first phase is data binding which occurs when you bind request parameters onto an instance such as... At this point you may already have errors in the errors property due to type conversion (such as converting Strings to Dates). You can check these and obtain the original input value using the Errors API. ... The second phase of validation happens when you call validate or save. This is when Grails will validate the bound values againts the constraints you defined."
The documentation for hasErrors also mentions this. You can access this by finding the method call in the navigation frame on the left, when you are on the documentation site. I would always recommend looking on these as well as the more descriptive user guide pages, as they often give a little more detail.
Here's the page for the validate method too.
I've never had a problem calling validate directly - it's very clear to me and I can choose the point where all the work is done and I'm ready for the validation to take place. I can't see an option to change this behaviour anywhere, but if you wanted validate to be called automatically or under certain conditions, you could perhaps use some Groovy meta programming magic by maybe adding invokeMethod to the class and have it call validate before passing certain calls on. Have a look here and here.
(Not sure I would recommend that though! And bear in mind your class would now be dependent on being used within the GORM validation framework, as that validate method might not otherwise exist).

Client-side model-level or form level validation with ASP.NET MVC3

I am using ASP.NET MVC3 with jQuery Validate + the unobtrusive validation support that comes with MVC3. Works great for almost everything, but I have one view where there is some view-wide validation that I need to do and I am not sure how to tap into the validation events that happen as part of MVC3+Validate+Unobtrusive. The actual validation will take just a few lines of code. I just don't know where to plug in that code.
I would like to tie into existing validation flow so that when the standard validation finds errors with individual fields and adds warning messages for them, my form-wide error message will also appear in the validation summary.
P.S. I am clear how to add appropriate model-level validation on the server side (Scott just blogged about it), but I feel it would be strange if some validation happened on the client and others only on the server. A user might see the client validation errors, fix them, then try to submit the form and only then get the model-level validation error message.
I would say what you are looking for is the new support for Remote Validation in Asp MVC3. Here is an article describing a common scenario, hopefully you can extend it yourself. Otherwise there are probably other articles around explaining it even better ;-)
http://www.aaronstannard.com/post/2010/12/07/remote-validation-asp-net-mvc3.aspx
/Victor
You should ALWAYS validate again on the server. Its really easy to circumvent javascript validation.
Rule #1 of Web Development: NEVER TRUST USER INPUT

How to get Model errors in AjaxSubmit?

I am using AjaxSubmit to post a form and there are server side validations done using XVal (RuleException way). I am not using the try/catch way to add error to Model and then send to view. Instead - I want to use the HandleError attibute and in the OnException I am adding the errors to Model. The major problem is how do I get those errors as a results in the Ajax Call?
There is not a great solution built in right now. Doing this correctly requires a client-side validation framework (because, to display the errors, you need to dynamically change the HTML page), and until recently, ASP.NET MVC has not had that. However, ASP.NET MVC 2 Preview 2 introduced client-side validation, so it's reasonable to presume that something might be built into the framework soon.
In the meantime, however, HandleErrorAttribute won't help you. HandleErrorAttribute only knows how to redirect to an error page, which is generally not what you want to do in response to a server-side validation error even with a "normal" POST, and certainly not with an AJAX post.
There really two different scenarios you need to handle:
Validation errors are not catastrophic failures; they are simply bad user data, which you should expect. You just need to get the information back to the page, so that the page can be marked up to tell the user how to fix their data.
You also need to handle catastrophic failures, like unanticipated exceptions. This is akin to what HandleErrorAttribute does, insofar as you can display a message to a user, but you cannot necessarily match that message up with specific fields on your page.
To handle the first scenario of error, you need to wrap the model state up into an object which will be parsable in JavaScript code; JSON is the obvious fit here. You then need to have JavaScript code on the client side which parses this object and marks up the form fields. This is easier if you tie into an existing client-side validation framework, which already contains code for marking up form fields.
To handle the second type of error, you can extend HandleErrorAttribute in order to provide JSON instead of HTML in the event of a catastrophic failure. Again, you will need to write JavaScript code that will be executed in the event of a failure -- jQuery's global ajaxError event is useful here -- that detects this structured error information you've created and display some sort of useful message to the user.
If all this sounds a bit involved, well, it is, which is why it may make more sense to wait and see what will be built-in when MVC 2 is finally released.

How to Unit Test Data Annotation Validators

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/

Resources