4 ms·
I don't see why TDD proponents make a big deal about not touching the database. It's as if they haven't heard of SQLite's in-memory option, in which the databas
by mwcampbell 13y ago
I don't see why TDD proponents make a big deal about not touching the database. It's as if they haven't heard of SQLite's in-memory option, in which the database is just another data structure in RAM, which is all that their extra layers of objects are. True, with that setup, you're using SQLite for tests and, say, PostgreSQL in production. But is that any worse than using your own mock objects in tests? What am I missing?
- mickeyp 13y agoSQLite is not <your actual rdbms>... it's SQLite. A database that does not enforce column types and lacks most of the advanced features of a real rdbms. Using SQLite will work great right up until the point where it won't and you get your fingers burnt. If you separate your concerns properly you won't need to mock the database layer either. Mocking is just one part of the trifecta of good testing, along with Stubbing and Faking. For most things it would make more sense to fake the database layer or stub the database layer in your "logic" layer. However, if your application makes heavy use of the rdbms then you should test that layer too: In your integration tests and not your unit tests. Most places that interact with an RDBMS treat them like black boxes and not like a business layer of its own. You really need integration tests to ensure things like constraints and your business rules are captured properly... most people never bother. The real problem with TDD and its methodologies isn't TDD itself; it's people shoehorning about 10% of what proper testing should be into two narrow groups: stuff that you can do with "unit tests" and "things we can mock." There's a lot more to it than just those two things.
- sanderjd 13y agoUsing SQLite's in-memory option is basically just a convenient way to get database mock objects. I don't personally think it's any worse (or better) than using mock objects. However, I think a reasonable argument for why they might be worse is that you've introduced a lot of fake code (as in, not used in the real application) that can cause false-negatives or false-positives in your tests. That's true of libraries for mocks too, but they introduce way less code.
- lmm 13y agoSQLite probably qualifies as a mock in the sense DHH is talking about - as another reply said, there's no clear sharp line between "unit" and "integration". But to answer your question, what you may be missing is performance. I don't object to tests that use the database on ideological grounds, I object because they're slow. In-memory databases are faster, but still much slower than a true unit test.
- kyllo 13y agoI think it's less that running database tests is bad, but more that your business objects (models) should not be so tightly coupled to your ORM. All of the business logic is supposed to go in the models, but the models inherit from ActiveRecord::Base so therefore you're stuck with ActiveRecord forever and you can't test any business logic until after you do a schema migration. It places the database at the center of the development process, because the first thing you have to do is design the database schema, before anything else will work. Instead, you really should be writing (and testing) business logic first, and figuring out what your objects/models are going to be through a gradual refactoring process. Then you can design your persistence schema after your objects and their relationships are fully fleshed out. Rails is really a database-driven development tool, but guys like Uncle Bob are arguing that database-driven development is an anti-pattern.