[Ruby] [Rails] From test preparation to model unit testing [RSpec]

4 minute read

Introduction

I will write about Rails testing.
This is a unit test of the model using RSpec. The main thing is to check if the validation works well.

Introducing RSpec

First, install the gem.
Edit the Gemfile and install bundle.

Gemfile


group :development, :test do
  gem 'rspec-rails'
end

# web-If the gem called console is in the test environment, move it only to development
group :development do
  gem 'web-console'
end

Terminal


$ bundle install

Next, prepare a file for rspec.

Terminal


$ rails g rspec:install

I think you’ve added some files.

Add the following to the .rspec of the added file.

.rspec


--format documentation

Next, prepare the necessary directories.

Create a spec / models directory

Next, create a file to write the test code in the models directory.
This time we will create post_spec.rb.
Let’s name the file model name_spec.rb.

Now you are ready to go.

Test code description

Let’s write the test code.

spec/models/post_spec.rb


require 'rails_helper' # rails_Required to use helper. Please write without thinking
describe Post do #About Post model
  describe '#create' do #About the create action
    it "Cannot register if there is no content" do #Describe the confirmation contents of the test
      post = Post.new(content: "") #Create an instance (data) of Post model
      post.valid? #When saving an instance, make sure that it cannot be saved due to validation.
      expect(post.errors[:content]).to include("can't be blank") #In the error statement"can't be blank"Determine if is included
    end
  end
end

Each process is as I wrote in the comment out, but if you check it one by one on the console, you can understand it a little more, so let’s try it!
Let’s launch the console screen in the terminal.

Terminal


$ rails c

Try executing the test code ʻit ~ end` in order.

ff85d977fcb5b51a8144d55c95468715.png
[1] An instance of the Post model (empty content column) is created here.
3ce62d1bbec5ec9557a79f44cbc6ab93.png
[2] If the instance created above fails to save, false will be returned.
For more information on valid? And invalid? Methods, please refer to here.

67d49b9cce2dfa00427194114ba6a853.png
[3] The error statement can be viewed using the errors method.
I’m getting an error message at @ message.
This time, in addition to the validation that does not allow the sky, the Post model also has a validation of at least 2 characters, so those two errors are appearing.

Useful tool (FactoryBot)

The Post model used in the above example had few columns and it was easy to create test data.
However, with a User model that has multiple pieces of information such as names, email addresses, and passwords, it is troublesome to write data one by one.

user = User.new(name: "hoge", email: "[email protected]", password: "xxxxxx")

You have to write it this way, which results in verbose code.

If you use a gem called ** FactoryBot **, you can prepare default data and change the data only where you need it, which is convenient.
I will write the introduction method and usage in order.

First, insert the gem.

Gemfile


group :development, :test do
  #abridgement
  gem 'factory_bot_rails'
end

Terminal


$ bundle install

Create a spec / factories directory.

Next, create a file to write the data in the factories directory.
This time I will create ʻusers.rb. Let's name the file model name plural .rb`.
The way to write is as follows.

spec/factories/users.rb


FactoryBot.define do

  factory :user do
    nickname              {"neko"}
    email                 {"[email protected]"}
    password              {"nyannyan"}
    password_confirmation {"nyannyan"}
    profile               {"hello"}
  end

end

You can easily create an instance with a spec file by using factory_bot.

user_spec.rb


user = FactoryBot.create(:user)

Just write and it will create an instance prepared in users.rb.

Actually, it’s a little easier to write, so let’s set it as well.

Omission of factory_bot notation
Add the following to rails_helper.

rails_helper.rb


RSpec.configure do |config|
  #Add the following
  config.include FactoryBot::Syntax::Methods
  # (abridgement)
end

Let’s use this to write a test for the User model, for example.

user_spec.rb


require 'rails_helper'

describe User do
  describe '#create' do

    it "Cannot register without nickname" do
      user = build(:user, nickname: "")
      user.valid?
      expect(user.errors[:nickname]).to include("Please enter")
    end

    it "Cannot register without email" do
      user = build(:user, email: "")
      user.valid?
      expect(user.errors[:email]).to include("Please enter")
    end

  end
end

You can create an instance by doing build (: model name) like this.
If you want to use a value different from the value prepared by factory_bot, such as empty data, you can use build (: model name, column name: value).

Run the test

All you have to do is enter a command from the terminal to run the test.

Terminal


$ bundle exec rspec  

fd3dba157c0da00633c15f6a630b06f2.png
If the test passes, it will be displayed like this.
If it fails, the number of feilures will be counted as many as the number of tests that did not pass, and the error content will be displayed.

Run test by specifying file

The command bundle exec rspec written above will execute the entire spec file, so if you already have a verified test, it will be a little wasteful.

Terminal


$ bundle exec rspec spec/Directory name/file name(_spec.rb

You can specify the file and execute it by.
Taking the test of the user model used this time as an example, it is as follows.

Terminal


$ bundle exec rspec spec/models/user_spec.rb