[RAILS] [RSpec] How to write test code

This time, using RSpec, the "new user registration function" I will explain how to write the test code of the model.

Basic form of test code

spec/models/user_spec.rb


require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'New user registration function' do
    context 'If it works' do
      it 'New user registration is possible if values ​​exist in all columns' do
       #processing
      end
    end

    context 'If it doesn't work' do
      it 'Cannot register if nickname is empty' do
       #processing
      end
    end
  end
end
end

The above is the "basic form" of the test code. I will explain the methods used and the meanings of related words one by one.


describe A method for grouping test code. Group "Which function to test for" by describe, Describe each test code in describe do ~ end.

Describe describe in describe using a nested structure. It is also possible.


context This method is used to group by specifying specific conditions. The usage is the same as describe, but the describe says "What is the test about?" Whereas the context specifies "specific conditions".


it This is also a method for grouping test code. In the case of it, describe in more detail "what kind of situation is to be tested in the function described in the describe method".


example It refers to the content described in it do ~ end, or the group itself divided by it. Speaking above, "If there are values ​​in all columns, you can register a new user", "Cannot register if nickname is empty" is an example.


How to write test code

spec/models/user_spec.rb


require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'New user registration function' do
    context 'If it works' do
      it 'New user registration is possible if values ​​exist in all columns' do
        expect(@user).to be_valid  
      end
    end

    context 'If it doesn't work' do
      it 'Cannot register if nickname is empty' do
        @user.nickname = ''       
        @user.valid?             
        expect(@user.errors.full_messages).to include("Nickname can't be blank") 
      end
    end
  end
end
end

I actually wrote the above test code. As a premise, the instances are grouped in advance with FactoryBot and assigned to @user. In other words, @user contains all the "values ​​required for successful new user registration".

Let's explain the meaning of the code.


Meaning of each code expect(@user).to be_valid This is testing @user with all the values ​​together. is what it means.

@user.nickname = '' This gets the nickname column from @user and The value is empty.

@user.valid? If the nickname in @user is empty, we are checking for errors.

expect(@user.errors.full_messages).to include("Nickname can't be blank") If @user has an error, retrieve the error message as an array. And if the error message contains "Nickname can't be blank" I'm checking.


The above is the general meaning of the code. Below, we will explain the methods and matchers that make up this code. Then please ↓

Methods and matchers

valid? A method that executes validation and determines if there is an error. Returns true if there are no errors, false if there are. If there is an error, it will generate an error message indicating the nature of the error.


be_valid A matcher that expects the return value of the valid? Method to be true. If the instance specified in the expect argument does not cause an error in validation, the return value of valid? Will be true and the test will succeed.

In other words, to summarize the description "expect (@ user) .to be_valid" this time "All the contents of @user are successful, I'll check it for the time being!"


expectation It is a syntax to check whether the behavior obtained by the verification is as expected. "Expect (). To matcher ()" is the template. Describe by changing the arguments and matcher according to the content of the test.


errors A method that returns the contents of an instance if there is an error.


full_messages This method retrieves error messages as an array from the contents of the error.


include It is a matcher to confirm that "argument of include" is included in "argument of expect". When applied to this code, in (@ user.errors.full_messages) Make sure it contains ("Nickname can't be blank") about it.


eq A matcher that confirms that the "expect argument" and the "eq argument" are equal. Not used in this code.


Recommended Posts

[RSpec] How to write test code
How to write an RSpec controller test
How to write good code
How to write test code with Basic authentication
[RSpec on Rails] How to write test code for beginners by beginners
How to write easy-to-understand code [Summary 3]
Introduce RSpec and write unit test code
Write code that is difficult to test
[SpringBoot] How to write a controller test
RSpec test code execution
Introduction to RSpec 1. Test, RSpec
How to write dockerfile
How to write docker-compose
How to write Mockito
How to write migrationfile
How to use "sign_in" in integration test (RSpec)
JUnit 5: How to write test cases in enum
How to write code that thinks object-oriented Ruby
Bit Tetris (how to write)
How to write java comments
[Refactoring] How to write routing
Great poor (how to write)
[Note] How to write Dockerfile/docker-compose.yml
[Rails] Test code using Rspec
How to write Junit 5 organized
How to write Rails seed
[Ruby] How to write blocks
How to write a unit test for Spring Boot 2
To implement, write the test and then code the process
[RSpec] How to test error messages set by Shoulda-Matchers
How to dynamically write iterative test cases using test / unit (Test :: Unit)
How to unit test Spring AOP
Studying Java # 6 (How to write blocks)
[Rails] How to write in Japanese
Write test code in Spring Boot
Baseball ball count (how to write)
How to write a ternary operator
How to test a private method with RSpec for yourself
Rails on Tiles (how to write)
[Rails] How to write exception handling?
How to write Java variable declaration
Y-shaped road tour (how to write)
How to erase test image after running Rspec test with CarrierWave
[Integration test code] How to select an element from date_select
I tested how to use Ruby's test / unit and rock-paper-scissors code.
How to filter JUnit Test in Gradle
[Basic] How to write a Dockerfile Self-learning ②
Summary of how to write annotation arguments
[Note] How to get started with Rspec
How to call Swift 5.3 code from Objective-C
[Java] How to output and write files!
How to test private scope with JUnit
How to write Spring AOP pointcut specifier
How to write and explain Dockerfile, docker-compose
How to count UTF-8 code points fast
AtCoder is called TLE and talks about how to write beautiful code
How to deploy
How to set different source / target versions for production code and test code
[Rspec] Flow from introducing Rspec to writing unit test code for a model
Efficient test code
Rails: How to write a rake task nicely