Continue Discussion 13 replies
January 2010

_11530211

One minor point: "I use should eql() here, which translates to assertSame()" actually, that's the same as assertEquals(). If you want assertSame() you need to use equal().

ri BasicObject#equal?: "is used to determine object identity"

1 reply
January 2010

disqus_0fZ0Rrscah

This is a great article. Would you be able to expand on/give examples of the refactorings you mention in your second-last paragraph, say in a future post?

1 reply
January 2010

jonkernpa

A thought popped into my head after seeing how your controller test didn't care what it passed, just that it forwarded some Object. (I also wondered if there was a test for the "passed in nil" fail path.) Anyway, that thought:

"Do you need to test the controller at all?"

What drove you to consider writing the test for this in the first place?

1 reply
January 2010 ▶ _11530211

jbrains

I got that wrong. Thanks. I have fixed it.

January 2010 ▶ disqus_0fZ0Rrscah

jbrains

I can't commit to doing that, but I highly recommend following the links and looking for examples there. Also, look at the books I have listed at my librarything.com account (jbrains) for even more and better examples.

January 2010 ▶ jonkernpa

jbrains

This controller method does more than just the behavior I checked in that one test. Even if it didn't, invoking a method and giving its result to another method is not usually Too Simple to Break. I agree that's a judgment call.

As for the nil case, I don't remember if I have a test for that. I'll have to look.

January 2010

tednaleid

I created a plugin for groovy/grails projects that takes this principle to the next level called "build-test-data". In grails, domain objects have constraints on them that determine which fields are required and what kinds of validation they need in order to be persisted.

The plugin adds a "build" method on all domain objects that will create and save a new instance of a domain object with all required fields populated with dummy data. You can then pass in any fields that you actually want to have specific values that matter to your test.

It turns your example above (groovy style code) from this:

Posting.build(
title: "irrelevant title",
content: "irrelevant content",
queuedAt: null,
published_at: null
)

Into this:

Posting.build()

You don't have to specify any values that you don't care about, it populates title, content, queuedAt, and publishedAt for you. If you did care about the title in your test, you'd just use:

Posting.build(title: "title that matters for test")

I'm not aware of any other rails/django/merb type frameworks with this addition to their testing frameworks, but I think it'd be possible to create something similar for all of them. With rails active record interrogation of the database constraints, it should be possible to do the same kind of thing.

1 reply
January 2010 ▶ tednaleid

jbrains

Very neat, Ted. A good-looking implementation of the ObjectMother pattern. As you say, I imagine it would take relatively little effort to create a plugin for Rails. Thanks for sharing.

November 2011

jbrains

I just found a nice, simple example of this. Read the section "Examples all have the same structure" in http://concordion.org/Techn...

January 2017

WardPoulisse

just wanted to mention that the link to the test data builder pattern is broken

1 reply
June 2017 ▶ WardPoulisse

jbrains

At long last, fixed. Thanks.

1 reply
July 2019 ▶ jbrains

pieteckhart

In the mean time it broke again ;)

1 reply
July 2019 ▶ pieteckhart

jbrains

I just followed the link and it works now. :shrug: