Learning testing from dynamic languages such as javascript and php, my experience with testing uploads or file creation was via actually creating a file during test, verifying its existence, and then erasing this file. When I tried this in C# using Moq, the tests wouldn't fail, but the file wasn't created.
I was missing something, so I found this excellent link on testing file uploads in asp.net http://www.hanselman.com/blog/ABackToBasicsCaseStudyImplementingHTTPFile...
After reading it over, I realized that:
1. The problem was that I was calling SaveAs() from HttpPostedFileBase class, not HttpPostedFile. As an abstract class, this method is not implemented. Moq must implement this method for one. Nice, nice Moq.
2. There is a nice couple of method called Verifiable() and Verify(), and they belong to the Mock object. My using it in the following manner
file1.Setup(f => f.SaveAs(It.IsAny())).Verifiable();
We can later called
file1.Verify();
And this will verify that the method got called. So there is no need for me to implement SaveAs() to test that it is being called.
Bonus aside:
Thinking back, it seems that I have learned many new concepts via scripting languages. I believe it is because the simpler language interface allows one to exercise the features more seemly by not having to think of elaborate setups.
Looking back at this, I realize now that I didn't fully understand how unit testing is supposed to work. My idea was that you test every function. To be honest, I actually still like my idea a lot, and judging by many of the unit test flame wars threads on different online forums, it seems that a lot of people feel the same way.
I believe that the crux of the problem stems from the principal that says thou shall not test private methods. The catechism answer for why is simple: that code gets tested when you test the public methods. Then the test private method camp asks what is the point of testing in the first place if you are not going to test what are potentially key functions. And most of the orthodox priests will repeat that private methods will be tested with the public methods.
So many pragmatic people just make their private methods public. Some keep it like that. Some turn them back to private before releasing the code.
Yet I remember having an insight during one of my unit test periods in that if you really need to test a set of private methods because they are very important, maybe they should belong to their own class --- ---- (the empty space represents the state of enlightenment that cannot be expressed with words.)
So there was a reason why testing should only happen to public units! If you feel compel to test some key private methods, it is because they probably belong on their own object. The principle helps us with the design!
Now, I thank my orthodox priest sensei for granting me that moment of enlightenment. After all, it feels very good; it makes me feel like I am smarter; and it gives me a moment where I feel connected with the full universe.
On the other hand, my sensei could have told me that to begin with, I would have seen the wisdom of it right away, and would have adopted the practice a lot sooner. Jerk. But then, maybe those monks are full of cattle waste and are just repeating some mantra that everyone learned somewhere else. What makes them think that they can go around doing that when they don't know what they are talking about?
On the other hand, being full of shit and a zen master is very Zen in itself. Oh, wait a minute, I think it is coming, oh... --- ----
This was complicated to set up, but I am finally running a case. I may have to write a more detailed set of instructions on how to set it up on 6.x. The good news is that it is part of core on 7.
Today I grabbed another low hanging fruit. This time it is Selenium. I had played with Selenium recorder a long time ago; I got to use Selenium recently, in a previous iteration of the current project that I am working on. At the time though, I was using Selenium mainly as a way to quickly populate a form before I actually tested it.
Even using Selenium IDE in this manner, just too quickly populate a form for manual testing, it is a huge time saver. Rather than testing every 10 minutes, one can test every couple of minutes.
But today I started moving towards using it for actual testing.
There are some issues that slow down quick adoption of the tool though.
Selenium IDE is quirky in my opinion. It doesn't behave the way I expected it to behave. I expect that the test, after I record it, will be saved. Instead, I have to manually save each case. Also, it would be nice if one could easily move the order of the tests around in a test suite. I found myself in the last few days having to create new suites just to switch the order.
And there is a conceptual switch that has to happen as well. It was only in the last few days that I realized that if the task cannot be completed, that is a test failure, not the equivalent of compilation error.
But even with these small limitations, and using it in this limited capacity, Selenium has already saved me a lot of time, and helped to bring my current project to successfully meet a very tight deadline. It has also been helpful in debugging a hard to find error, and helped to speed up integrating the system on the deployment site.
So you are going to hear a lot more about Selenium here in the near future.
After doing some research, it seems that there is no clear way to unit test asp .net WebForms.
ASP .Net web forms behavior collides with the current testing principles. The big one being that you only test public methods. Well, it seems that most Web Form pages don't have ANY public methods, making it impossible to test following the unit test principle. For those developers that want to do testing, it means that they have to expose the different private methods that they are using as public methods, breaking a big principle in OOD, which is that public methods are the interface to the object. So the developer who wants to unit test their code either breaks the principle of not testing privates or breaks the OOD principle of exposing as little interface as possible.
So the solutions that I have found either involves some complex code bending to allow for the testing of private methods, doing weird practices such as exposing private methods as public.
The other big solution seems to be to move to the MVC framework. Ideal solution for new projects if one has the time to learn the framework, but won't help that much if one has to work with legacy code.
The one idea that popped into my mind as I was writing this is that maybe it is possible to mvc-ize a bit the code. If every interaction of the page has to rely on objects, then we can test those objects. This seems to have some limitation in that separating database interactions may be difficult, impossible, or create greater problems that it attempts to solve. But at least it, if used properly, allow for testing of potentially breakable parts of the code.
I will experiment with this idea and see what happens.