0
\$\begingroup\$

I have a FactoryGirl page that generates same data but in two different languages. The variable names are the same. How do I write it in the smartest way possible without having to write a huge bunch of code?

    FactoryGirl.define do
      factory :static_page do
        language ""

        trait :purchase_loan do
          page_name "Purchase Loan Wizard"
          titlebar_text "Home Loan Wizard -Compare and find the best home loan in Indonesia"
         language "en"
        end

        trait :refinance_loan do
          page_name "Purchase Loan Wizard"
          titlebar_text "Rumah Kita Wizard -Dah Bayar rumah Best di Indonesia"
          language "ms"
        end

      end
    end
\$\endgroup\$
2
\$\begingroup\$

You can use I18n directly in factory definitions

FactoryGirl.define do
  factory :static_page do
    language "en"
    trait :purchase_loan do
      page_name { I18n.t("static_page.page_name.purchase_loan", locale: language) }
      titlebar_text { I18.t("static_page.titlebar_text.purchase_loan", locale: language) }
    end

    trait :refinance_loan do
      page_name { I18n.t("static_page.page_name.refinance_loan", locale: language) }
      titlebar_text { I18.t("static_page.titlebar_text.refinance_loan", locale: language) }
    end
  end
end

This will allow you to share locales in views / application code and in your tests.

But you could go 1 step further and in your model store only locale keys, ie.

class StaticPage < ActiveRecord::Base
  #attribues in db :pagename, :titlebar, :language
  def pagename_text
    I18n.t(pagename, locale: language)
  end

  def titlebar_text
    I18n.t(titlebar, locale: language)
  end
end

then you can use it this way:

purchase_loan_en = StaticPage.create(language: 'en', page_name: 'static_page.page_name.purchase_loan')

this will allow you to remove translations directly from factories.

Have a look on I18n Rails guide for how to use I18n. Maybe you don't even need to store language in database.

\$\endgroup\$
1
\$\begingroup\$

I'm betting that a lot of the time, you (or rather, your tests) do not care about the actual text. It could just be "lorem ipsum" for any language. And when you do need the created model to say something specific, you can pass those values to create/build.

Besides, it doesn't makes sense for your tests to check an attribute in a model generated by FactoryGirl. That's not testing the actual site/app in any way; you just check that your factory works as intended, but so what?

E.g. if you have a test that checks a page's title is set to "Purchase Loan Wizard", you're being too specific. What you want to test is that the page's title is whatever the model says is should be: If the model's titlebar_text is "asdlhwnkf" then that's what the page's title should be. No need to care about the actual content.

Also, the way your factory's set up right now, there's no functional difference (as far as I can tell) between the two traits. It's just text.

So simplest option:

FactoryGirl.define do
  factory :static_page do
    language "en"
    page_name "page name"
    titlebar_text "titlebar text"
  end
end

And done. Just override attributes when you create/build, if you need to.

If you do need the model to have localized content, I'd suggest using Rails' built-in localization features. Perhaps something like:

static_page = FactoryGirl.create(:static_page, page_name: I18n.translate!("path.to.some.localized_page_name_string"))

Here's a somewhat related question about localizations in tests.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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