Testing declarative code

I’m a little conflicted about how and if one should write test code for declarative code. Let’s say I’m writing a MongoMapper document class. It might look something like this:

class Issue

  include MongoMapper::Document

  key :title, String
  key :body, String
  key :created_at, DateTime

end

Those key calls. Should I write a test for them? In the past, I’ve said “yes” on the principle that I was test driving the code and I needed something to fail in order to add code. Further, the growing ML-style-typing geek within me likes that writing tests for this is somewhat like constructing my open wacky type system via the test suite.

A Shoulda-flavored test might look something like this:

class IssueTest < Test::Unit::TestCase

  context 'An issue' do

    should_have_keys :title, :body, :created_at

  end

end

Ignoring the recursive rathole that I’ve now jumped into, I’m left with the question: what use is that should_have_keys? Will it help someone better understand Issue at some point in the future? Will it prevent me from naively breaking the software?

Perhaps this is the crux of the biscuit: by adding code to make certain those key calls are present, have I address the inherent complexity of my application or have I imposed complexity?

I’m going to experiment with swinging back towards leaving these sorts of declarations alone. The jury is still out.

3 thoughts on “Testing declarative code

  1. I’d say leave that test out, and also leave the key declarations out until they’re storing data you need for some behaviour. I presume the ‘key’ statements both set up (a) an accessor on the attribute, and (b) persistent storage of the values – testing plain readers/writers doesn’t gain much IMO, and you’ll be testing storage in general at higher level tests.

  2. You make a good point about testing accessors. However, I like the _idea_ of testing the contract of a class, and accessors are certainly part of the contract. But liking the idea does not mean I’m going to stick with it in practice ;)

  3. I’ve had this exact same problem, but I don’t know the answer :(

    I wrote a bunch of rspec macros to reduce my previously multi-line specs which test various model declarations down to a single line, but then found myself in the same situation you describe…

    My thinking at the moment is that duplicating a model declaration with a spec declaration is pointless, and not very dry. Any getter/setter tests should be abstracted up to the DSL library level and the model declarations left to speak for themselves. I could be wrong though :)

Comments are closed.