5
\$\begingroup\$

I am using code like this everywhere. How can I reduce such this code so that my Ruby code looks a lot cleaner?

Fabricate(:tl, :when =>Date.yesterday.to_s,:work => 266,:type => "fast" )
Fabricate(:tl, :when =>Date.yesterday.to_s,:work => 100,:type => "super_fast" )
Fabricate(:tl, :when =>Date.yesterday.to_s,:work => 50,:type => "ludicrous" )
Fabricate(:tl, :when =>Date.yesterday.to_s,:work => 900,:type => "budget" )
\$\endgroup\$

4 Answers 4

6
\$\begingroup\$

I found that I can use hash({}).each method to dry up the code. It is :

{"fast"=>266, "super_fast" => 100, "ludicrous" => 50, "budget" => 900}.each{ |key, value|
  Fabricate(:tl, :when =>Date.yesterday.to_s,:work => value,:type => key )
}

If there is a better technique, please share it.

\$\endgroup\$
4
\$\begingroup\$

How about just defining a new facade method and calling that as many times as needed? You can put in some sanity checking on the arguments that way. Say for example, we had:

def fixture(attrs)
  raise ArgumentError unless Hash === attrs
  key = attrs.keys.first

  Fabricate(:tl, :when => Date.yesterday.to_s,
            :work => key.to_s, :type => attrs[key])
end

Then you could create your objects like so,

fixture :ludicrous => 50
fixture :super_fast => 100
fixture :fast => 266
fixture :budget => 900

You're still calling the same method multiple times, but I think it reads better that way.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I like the fixture. Much easier to read. \$\endgroup\$
    – IAbstract
    Aug 26, 2011 at 21:46
  • \$\begingroup\$ I agree, more explicit while being clear. \$\endgroup\$ Aug 27, 2011 at 3:06
4
\$\begingroup\$

Tools like Fabricator are already designed to reduce duplication, while establishing a convention so that every example has exactly what it needs. Adding a fixture method adds another layer of indirection that makes it that much more challenging to understand what's supposed to be happening in an example. I'd recommend, instead, using Fabricator as intended.

Let's say a Person needs to be 18 years or older to do certain things on a site. You'd set up a fabricator like this:

Fabricator(:person, :birthdate => Date.today - 18.years)

Now, in most examples you'd just say Fabricate(:person), but in the example specifying that an underaged person is not allowed to do something you'd say:

Fabricate(:person, :birthdate => Date.today - 18.years + 1.day)
\$\endgroup\$
1
  • \$\begingroup\$ This is absolutely the right way to do it. \$\endgroup\$ Oct 21, 2011 at 21:28
2
\$\begingroup\$

I may be in the minority here but I have always been a fan of not DRYing test code. I think when you try to dry things you end up becoming less agile. Rather you want your tests to be as specific as possible to each case.

I know this is not possible for example you may want to DRY up logging into the program, or navigating to an admin panel but drying up something like the accepted answer only does one thing to your code. Makes it less readable to your tests. That is make them less readable to a lay person or a new comer.

That in my opinion is what tests are all about.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I've heard other people say this, but I think they're wrong. Removing repetition from test code usually leads to more readable test code in my experience. \$\endgroup\$ Oct 21, 2011 at 21:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.