Jumat, 13 Mei 2022

Setup RSpec Ruby on Rails API Mode dengan Serializer & Factory Bot Bagian 2

Di Rails, serializer memungkinkan Anda untuk menyesuaikan data alih-alih memiliki render default.

Pada artikel ini, kita akan melihat panduan langkah demi langkah untuk menggunakan serializer di aplikasi Anda. Berikut dengan implementasi Rspec pada Serializer.


1. Tambahkan gem serializer pada Gemfile

gem 'active_model_serializers'

kembali ke terminal dan run 

 bundle install 

2. membuat sebuah file Serializer

 bundle exec rails g serializer Customer



edit app/serializers/customer.rb tambahkan validasi

 class Customer < ActiveModel::Serializer  
  attributes :name, :email
 end  

pada contoh file diatas response pada json customer akan menampilkan attributes name & email.

fungsi file serializer sendiri dapat digunakan untuk mengkustom response sesuai kebutuhan response pada front end.

3. Install Factory Bot

Tambahkan gem factory bot pada Gemfile pada group :development, :test

gem 'factory_bot_rails'

4. Konfigurasi factory bot 

Berhubungan dengan tutorial sebelumnya pada tutorial ini Kita masih menggunakan model Customer.rb.

lalu buka terminal unutk membuat file factory pada folder rspec dengan menjalankan command

rails g factory_bot:model customer

setelah menjalankan command diatas, otomatis akan terbuat file seperti ini



setelah file spec/factories/customers.rb terbuat

konfigurasi file factory customers.rb seperti dibawah

FactoryBot.define do 
  factory :customer do |f|
    f.name {Faker::Name.name}
    f.email {Faker::Internet.email}
   end
end 

5. Konfigurasi RSpec dengan Serializer & Factory Bot

tambahkan folder dan file seperti ini spec/support/serializer_spec_helper.rb

lalu tambahkan baris kode seperti dibawah

module SerializerSpecHelper
  def serialize(obj, opts={})
    serializer_class = opts.delete(:serializer_class) || "#{obj.class.name}Serializer".constantize
    serializer = serializer_class.send(:new,obj)
    adapter = ActiveModelSerializers::Adapter.create(serializer, opts)
    adapter.to_json 
  end  
end 


Setup konfigurasi RSpec dengan factory bot, tambahkan file spec/support/factory_bot.rb

lalu tambahkan kode dibawah ini

RSpec.configure do |config|
 config.include FactoryBot::Syntax::Methods  
end 
Tambahkan kode dibawah pada file spec/rails_helper.rb, untuk RSpec bisa mendeteksi file pada folder support/ dan serializer_spec_helper.rb.

 Dir [Rails.root.join('spec', 'support', '**', '*.rb'].sort.each { |f| require f}
 RSpec.configure do |config| #sisipkan kode dibawah 
 config.include SerializerSpecHelper, type: :serializer 


6. Setup Skenario Test RSpec Serializer & FactoryBot


Contoh kasus front end membutuhkan response data seperti berikut:
[
{
"name": "Persada Ersad",
"email": "ersad@doterb.com"
}
]

Testing  RSpec untuk CustomerSerializer menghasilkan, response data seperti contoh kasus diatas.

Tambahkan kode dibawah pada folder dan file spec/serializers/customer_serializer_spec.rb
require 'rails_helper'  
 RSpec.describe CustomerSerializer, :type => :serializer do
  customer = FactoryBot.create(:customer)
  serializer = CustomerSerializer.new(customer)
  describe 'attributes' do
    it { expect(serializer).to include(:name, :email) }

    it 'returns data should be contain name and email' do
      expect(serializer).to include(
        name: customer.name,
        email: customer.email
      )
    end
  end
end 

Selanjutnya balik ke terminal dan ketikan command

rspec



Kita coba untuk mempraktekan jika ada kesalahan data pada response CustomerSerializer

pada file app/serializers/customer_serializer.rb hapus kode ':email'

class CustomerSerializer < ActiveModel::Serializer
  attributes :name
end

Selanjutnya balik ke terminal dan ketikan command

rspec

hasilnya akan ada failure test seperti dibawah ini:












Selamat mencoba & Cheers :D 

Tutorial Created By: Doterb | Persada Ersad

Kamis, 12 Mei 2022

setup Rspec Ruby On Rails API Mode bagian 1

RSpec adalah kerangka kerja pengujian unit untuk bahasa pemrograman Ruby. RSpec berbeda dari kerangka xUnit tradisional seperti JUnit karena RSpec adalah alat pengembangan yang digerakkan oleh Perilaku. Artinya, tes yang ditulis dalam RSpec berfokus pada "perilaku" aplikasi yang sedang diuji.

RSpec adalah DSL untuk membuat contoh yang dapat dieksekusi tentang bagaimana kode diharapkan berperilaku, terorganisir dalam kelompok. Itu menggunakan kata-kata "describe" dan "it" sehingga kita bisa mengungkapkan konsep seperti percakapan:

"Describe an account when it is first opened."
"It has a balance of zero."

1. setup dan install ror and rspec

Buat aplikasi baru dengan command berikut 

rails _7.0.1_ new sample_unit_test --api -d postgresql

pindah ke directory yang kita buat

 cd sample_unit_test 

buka file Gemfile tambahkan gem 'rspec-rails'

kembali ke terminal dan run 

 bundle install 

create database dengan run 

 bundle exec rake db:create 

setup rspec ke rails dengan command berikut

bundle exec rails generate rspec:install  

2. membuat sebuah model customer dan fitur crud  yang akan kita test fiturnya

 bundle exec rails g scaffold customer name:string phone:bigint email:string address:text
bundle exec rake db:migrate

edit app/models/customer.rb tambahkan validasi

 class Customer < ApplicationRecord  
  validates :name, :email, presence: true  
 end  

3. update rspec file 
pada saat kita melakukan run  command scaffold  ror akan otomatis membuatkan file testnya juga

Gambar Hasil generate scaffold


untuk melakukan test pada controller customer edit file di spec/requests/customers_spec.rb
isi nya sebagian sudah ada di generate by system oleh ror tapi belum sempurna ada beberapa perbaikan pada params dan assertions kita harus pelajari code yang sudah ada di mulai dari index show create update dan delete dan juga harus paham dengan assertions dan matchers

isi default dari file test request customers

 Karena isinya masih kosong kita harus mengisikan attribute yang benar dan attribute yang salah gunakan gem "faker" untuk membantu membuat data sesuai
let(:valid_attributes) do  
   { name: Faker::Name.name,  
    phone: Faker::Number.number(digits: 12),  
    email: Faker::Internet.email,  
    address: Faker::Address.street_address }  
  end  
   
  let(:invalid_attributes) do  
   { name: nil,  
    phone: nil,  
    email: Faker::Internet.email,  
    address: Faker::Address.street_address }  
  end  
   
  let(:valid_headers) do  
   {}  
  end 

valid headers dikosongkan karena di tutorial ini tidak memakai security token 

setelah menambahkan valid_attributes dan invalid_attributes coba test dengan comand berikut
bundle exec rspec spec/requests/customers_spec.rb 
Gambar setelah update valid dan invalid attribute


pada keterangan errornya ada dua proses yang pending itu dikarenakan ada skip waktu bagian update
buka kembali file berikut
spec/requests/customers_spec.rb 

Gambar default code part update


bagian skip harus diganti sesuai keterangannya untuk new atrribute maksudnya isi data new_attributes untuk menggantikan data lama isinya seperti code dibawah
    let(:new_name) { Faker::Name.name }  
    let(:new_attributes) do  
     { name: new_name,  
      phone: Faker::Number.number(digits: 12),  
      email: Faker::Internet.email,  
      address: Faker::Address.street_address }  
    end 

untuk bagian "assertions" kita isi dengan pengecekan data nama setelah update sama dengan nama pada new_attributes
    it 'updates the requested customer' do  
     customer = Customer.create! valid_attributes  
     patch customer_url(customer),  
        params: { customer: new_attributes }, headers: valid_headers, as: :json  
     customer.reload  
     expect(customer.name).to eq(new_name)  
    end 
check kembali file test dengan command berikut
bundle exec rspec spec/requests/customers_spec.rb 

Gambar hasil pengujian sukses tanpa gagal



Test model customer update spec/models/customer_spec.rb seperti berikut  kemudian run testing
 require 'rails_helper'  
 RSpec.describe Customer, type: :model do  
  it 'is not valid without a name' do  
   customer = Customer.new(name: nil)  
   expect(customer).to_not be_valid  
  end  
  it 'is not valid without a email' do  
   customer = Customer.new(email: nil)  
   expect(customer).to_not be_valid  
  end  
 end 
testing untuk model customer disini cuma validasi sebenarnya bisa banyak tergantung isi dari modelnya