ASP.NET MVC TDD with LINQ and SQL Database

I am trying to start a new MVC project using tests, and I thought the best way is to have 2 databases. 1 for testing against and 1 for when I run the application and use it (also actually check while it is not ready yet).

For a test database, I thought about creating scripts to create tables and populating data scripts in the test setup method, and then removing all of this in the stall method.

Am I going to use Linq to SQL, although I don’t think it will allow me to do this?

Do I just need to go the ADO route if I want to do it like this? Or should I just use a mock object and store the data as an array or something like that.

Any tips for best practices?

How did Jeff keep doing this for StackOveflow?

+6
sql tdd linq asp.net-mvc
source share
6 answers

I checked the connection with tvanfosson and RikMigrations, and after playing with them, I prefer the mocking datacontext method best. I realized that I do not need to create tables and constantly drop them.

After a little research, I found Steven Walter's article http://stephenwalther.com/blog/archive/2008/08/17/asp-net-mvc-tip-33-unit-test-linq-to-sql.aspx , which for It seems simpler and more reliable to me.

So, I'm going with this implementation.

Thanks for the help.

+2
source share

What I am doing is defining an interface for the DataContext shell and using the shell implementation for the DataContext. This allows me to use an alternative, fake DataContext implementation in my tests (or mock it if it's easier). This completely abstracts the database from my unit tests. I found the starter code http://andrewtokeley.net/archive/2008/07/06/mocking-linq-to-sql-datacontext.aspx , although I extended it so that it handles validation implementations on my object classes.

I should also mention that I have a separate intermediate server for QA, so there is live testing of the entire system. I just do not use the actual database in my unit testing.

+4
source share

You might want to find some other way to actually get into the database for your unit tests, because it takes a lot more time. Do you think that you used the use of Migrations to create / delete tables instead of using sql scripts? RikMigrations is what I used to create my database, so I can easily review all my code in one place. Justin Etheredge has an excellent article on using RikMigrations .

+1
source share

I agree with most of the above regarding unit testing. However, I consider it important to emphasize that the use of Mock Repositories and unit tests does not give you the same level of tests as the database integration test.

For example, our databases often have cascading deletes built right into the schema. In this case, deleting the primary object in the aggregate will automatically delete all child objects. However, this will not be automatically applied in the mock repository, which was not backed up by a physical database with these business rules (unless you built all these rules in Mock). This is important because if someone comes and changes the design of my circuit, I need it to break my tests so that I can adjust the code / circuit accordingly. I appreciate that this is Integration Testing, not Unit Testing, but thought it was worth mentioning.

My preferred option is to create a master design database containing data samples (the same data that you will create in your Mocks). During the start of each test run, I have an automated script that backs up MasterDB and restores it to "TestDB" (which uses all my tests). Thus, I maintain a repository of clean test data in the Wizard, which recreates myself with each test. My tests can reproduce data and check all the necessary scripts.

When I debug the application, I have another script that backs up and restores the main database to the DEV database. I can play with the data here without worrying about losing my data. Usually I do not run this particular script every session because of the delay waiting for the database to recover. I can run it once a day and then play / debug the application during the day. If, for example, I delete all records from the table as part of my debugging, I would run a script to recreate DevDB when done.

These steps sound as if they would add a tremendous amount of time to the process, but in reality - they do not. Our application is currently located in the area of ​​3,500 tests, with about 3,000 of them gaining access to the database at some point. Backing up and restoring a database usually takes about 10-12 seconds at the beginning of each test run. And since the whole set of tests is performed only when checking TFS, we do not mind if we have to wait even longer. On average, our entire test suite takes about 15-20 minutes a day.

I appreciate and agree that integration testing is much slower than unit testing (due to the inherent need to use a real database), but it more closely represents a real-world application. For example, DB error codes are not returned to Mock Repositories, not a timeout, they are not blocked, they do not have enough disk space, etc.

Unit tests are approved for simple calculations, basic business rules, etc., and, of course, they are absolutely the best choice for most operations that are not related to access to the database (or other resource). But I do not think that they are as valuable as integration tests - people talk a lot about unit tests, but they say little about integration tests.

I expect those who are passionate about unit tests to send me flames. This is good - I’m just trying to bring some balance and remind people that projects that are full of passed unit tests can still fail the moment you implement them in the field.

+1
source share

This article provides an example of linq mocking on sql using typemock.

http://blog.benhall.me.uk/2007/11/how-to-unit-test-linq-to-sql-and.html

0
source share

All Articles