Replace fixtures with Factory-girl to create mock data
Fixtures
As we described earlier, the rails test system uses fixtures to create mock data, which are written in YAML format and placed in Db/fixtures folders, each with a corresponding file, test/fixtures/ Users.yml.
The data in these fixtures are loaded into the test database at the time the test is started and loaded into the variable for unit and functional testing.
There are several disadvantages to using fixtures, which puts them in a disadvantageous position.
One of the main factors is that these fixtures describe the data and test their behavior to be separate in different files. Using these analog data, we need to rely on fixtures files, which are difficult to read and maintain.
Let's say we need two user objects to test whether our user.authenticate is working properly, and we need to write the following.
Bob:
username:bob
email:bob@example.com
password_digest:3488f5f7efecab14b91eb96169e5e1ee518a569f
password_salt:bef65e058905c379436d80d1a32e7374b139e7b0
admin:
username:admin
Email: admin@example.com
password_digest:3488f5f7efecab14b91eb96169e5e1ee518a569f
password_salt: Bef65e058905c379436d80d1a32e7374b139e7b0
Since both of these data need to be stored in the database, our password_digest and password_salt need to look like this, and we can't know what the value of these two attributes means, what exactly is their content?
In the final part of the http://guides.rubyonrails.org/testing.html, a fixtures alternative is recommended, which is Factory girl, which also has a rails version factory Rails, specifically for rails testing.
How to use Factory girl rails in Rails
A detailed tutorial on the use of Factory-girl in Https://github.com/thoughtbot/factory_girl/wiki is generally applicable to factory-girl-rails.
Let's take a look at the basics of how to use this.
First, add in the Gemfile file
Gem ' Factory_girl_rails '
And then execute
Bundle Install
Then create the factories.rb file in the test directory. The function of this file is a bit like the Yml file we used to use fixtures to create mock data. But the difference is that the data in the fixtures will be automatically joined to the database, so the declared attributes are created to match the database, which is a kind of analog data from the database. However, the Factory-girl created by the simulation data will not be automatically added to the database, is a model from the simulation data, so the declaration of attributes and model corresponding, so will not appear when the use of fixtures what kind of do not understand the Password_ Digest property value.
Factorygirl.define do
factory:user do
nickname "nickname"
email "
ee@123.com" password "123" Password_confirmation "123"
end
The above factory-girl creates a user object that can also be used for testing purposes. Please note factory: After the full content, so to correspond to a model of the class name, the first letter is best lowercase, of course, uppercase is also possible.
You also need to introduce a module in the place where you use this data. If we want to use Factory-girl's analog data in the user's unit test, you can add this module to the following.
Class Usertest < Activesupport::testcase
include factorygirl::syntax::methods
end
In this way, we can use the mock data as follows in the user's unit test.
# Save user data to database
user = Create (: User)
# do not save user data, just save it to user variable
user = Build (: User)
# Gets the key value of the user property defined in Factory-girl to hash
user_attributes = attributes_for (: User)
# Creates a stub object for the user
User_ Stub = build_stubbed (: User)
# Overwrite Some properties of the user object in Factory-girl
user = Create (: User, first_name: ' Joe ')
However, if we have a lot of models, all need to simulate data, are written in the factories.rb file, it seems not very good, more write longer, and the content is mixed, it is not good maintenance, also not conducive to reading.
We can create the USERS.RB in the Test/factories folder and then test/factories the folder, and write the user's mock data in users.rb. You can also create files in the Factories folder that simulate other model uses.
But the above Factory-girl just creates a user object, what if you need more than one impersonated user object? You can write as follows: Class =>: User, to specify that the current object uses the user's model as the template.
Factorygirl.define do
factory:user1,: Class =>: User do
nickname "nickname"
Email "ee@123.com"
Password "123"
password_confirmation "123"
end
Factory:user2.: Class =>: User do
nickname " Nickname2 "
Email" ee2@123.com "
password" 1232 "
password_confirmation" "123
"
end
Two user objects were created above. You can use them as follows.
def test_use_valid_user_from_factory_girl
user = Build (: User1)
assert user.valid?
End
def test_use_invalid_user_from_factory_girl
user = Build (: user2)
assert user.invalid?
End
I have added a large number of unit test in Https://github.com/woaigithub/blog, you can refer to, you can also make comments, welcome to comment!
This article is from the "It architects in the breakout" blog, please be sure to keep this source http://virusswb.blog.51cto.com/115214/1076069
See more highlights of this column: http://www.bianceng.cn/Programming/project/