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

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](https://railsguides.jp/active_record_validations.html#valid-questionmark% E3% 81% A8 invalid-questionmark). 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

Recommended Posts

[Rails] From test preparation to model unit testing [RSpec]
[Rspec] Flow from introducing Rspec to writing unit test code for a model
[Rails5] Rspec -Unit test when nesting-
About app testing RSpec (unit test)
Let's unit test with [rails] Rspec!
[Rails] Unit test code for User model
[Ruby on Rails] Model test with RSpec
[Rails] Test with RSpec
[Rails / RSpec] Write Model test (using Shoulda Matchers / FactoryBot)
Introduction to Micronaut 2 ~ Unit test ~
[Rails] Test code using Rspec
[Rails] About Rspec response test
I tried unit testing Rails app using RSpec and FactoryBot
[Rails] Integration test using Capybara (from introduction to simple test execution)
[Challenge CircleCI from 0] Build an automated test (Rails6.0, mysql8.0, Rspec)
How to unit test Spring AOP
[RSpec on Rails] How to write test code for beginners by beginners
Password dummy data generation notes in Rails model unit test code
[RSpec] Unit test (using gem: factory_bot)
From pulling docker-image of rails to launching
Introduce RSpec and write unit test code
[Ruby on Rails] View test with RSpec
[Rails] How to convert from erb to haml
Java Artery-Easy to use unit test library
I want to write a unit test!
[Ruby on Rails] Controller test with RSpec
[Rails] Assigning variables from controller to JavaScript
What is the model test code testing
After introducing RSpec, until you start writing unit test code for your model
[Rails] I want to test with RSpec. We support your step [Introduction procedure]
[Rails] I tried to raise the Rails version from 5.0 to 5.2
How to link Rails6 Vue (from environment construction)
Rails Tutorial Chapter 1 From Zero to Deployment [Try]
[Rails] How to implement unit tests for models
Introducing Rspec, a Ruby on Rails test framework
I want to play with Firestore from Rails
Rails beginners tried to get started with RSpec
[Rails] Introducing pay.jp (from view customization to registration)