I have already had some difficulties on unit tests and I am trying to learn it while using a small project I currently am working on and I ran into this problem these two problems that I hope you can help me with
1- My project is an MVC project. At which level should my unit tests start? They should focus only on the business layer? Should they also test actions on my controllers?
2- I have a method that verifies an username format and then access the DB to check if it is available for use. The return is a boolean whether this username is available or not. Would one create a unit test for such a method? I would be interested on testing the format verification, but how would I check them without querying the DB? Also, if the formats are correct, but the username is already in use, I will get a false value, but the validation worked. I could decouple this method, but the DB verification should only happen if the format is correct, so they should somehow be tied. How would someone with unit tests knowledge solve this issue. Or how would someone refactor this method to be able to test it? I could create a stub for the DB access, but how would I attach it to my project on the user testing but detach it when running locally?
Thanks!
In your specific case, one easy thing you could do is decompose your verification method into 3 different methods: one to check formatting, one to check DB availability, and one to tie them both together. This would allow you to test each of the sub-functions in isolation.
In more complex scenarios, other techniques may be useful. In essence, this is where dependency injection and inversion of control come in handy (unfortunately, those phrases mean different things to different people, but getting the basic ideas is usually a good start).
Your goal should be to decouple the concept of "Check if this username is available" from the implementation of checking the DB for it.
So, instead of this:
public class Validation
{
public bool CheckUsername(string username)
{
bool isFormatValid = IsFormatValid(username);
return isFormatValid && DB.CheckUsernameAvailability(username);
}
}
You could do something like this:
public class Validation
{
public bool CheckUsername(string username,
IUsernameAvailabilityChecker checker)
{
bool isFormatValid = IsFormatValid(username);
return isFormatValid && checker.CheckUsernameAvailability(username);
}
}
And then, from your unit test code, you can create a custom IUsernameAvailabilityChecker
which does whatever you want for testing purposes. On the other hand, the actual production code can use a different implementation of IUsernameAvailabilityChecker
to actually query the database.
Keep in mind that there are many, many techniques to solve this kind of testing problem, and the examples I gave are simple and contrived.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With