开发者

Rails: create a fixture for arbitrary text data to use for integration tests

The Idea

I am creating a parsing method on an object so I can do this:

@address = Address.parse("123 Main St, San Francisco CA")

I want to build a library of potential user inputs ("supported formats", etc) that I can use to make sure that complicated regex changes in one place don't break others.

I want to create lots and lots of unit tests (should probably call them integration tests) for this functionality, and I would like to use fixtures for it:

fixtures/address_inputs.rb

one:
  address: 123 Main St, San Francisco CA
two:
  address: 234 Center Road San Francisco, CA

Then I can loop through all the fixtures to validate the r开发者_运维技巧esulting data in the object:

@addresses.each do |address|
  assert_true address.street_number.to_i > 0
end

or something similar.

The Problem

However, I can't use the fixtres since the data is not related to an ActiveRecord table. I get lots of errors like this:

ActiveRecord::StatementInvalid: SQLite3::SQLException: no such table

How can I create a test fixture to unit test arbitrary input? Should I use a different tool for handling these integration tests?


Eh... I would say this is a bad idea. When looking at a unit test I prefer to see what it's doing, so if you have a test that checks that the street number is getting pulled out correctly, your test might look like this (this is without knowing what your intention is with the function):

@address = Address.parse("123 Main St, San Francisco CA")
assert_equal @address.street_number, "123"

But if you used a 'fixture' (or some data stored in an external file) the test will be more difficult to read for you later, and for another developer later down the road (Note that I don't use fixtures, I prefer factory_girl, so I made the syntax up. It's probably wrong, but the point is made):

@address = Address.parse(fixture(:address_one))
assert_equal @address.street_number, "123"

Why are you asserting that the street_number is "123"? it's difficult to see if the test is even written correctly if an issue comes up later down the road. You have to go to the external file and it's just a real big pain in the butt.

I do find external fixtures (again, I use factory_girl) useful to setup certain states of objects like this:

Factory.define :user do |f|
  f.sequence(:email){ |n| "testemail#{n}@example.net" }
  f.first_name "Test"
  f.last_name  "User"
end

Factory.define :admin_user, :parent => :user do |f|
  f.admin true
end

That way I can always create an admin_user for a test when I need to, and if the definition of what makes a user an admin changes it's easier to make all the tests that rely on it correct. However this isn't done to test specific behavior of the @user.admin attribute, but more like permission things like "can the user access this action?"

If I were to use the :user factory later and wanted to test specific behavior of the 'email' attribute I wouldn't rely on what the factory supplied. I would create the object like this:, overriding the default email field:

@user = Factory.create(:user, :email => "myemail@example.net")

To make the test clearer.

I think your example is inappropriate where you'd be relying on the string of text in the fixture to determine what your assertions look like.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜