DEV Community

Vasily Polovnyov
Vasily Polovnyov

Posted on

3

RSpec & Rails: how to test callbacks

Sometimes it's not clear which way to approach a complex callback and how to test it. For example, in the situation with a post:

class Post < ApplicationRecord
  before_save :set_permalink
  after_save :rebuild_preview

  private

  def set_permalink
    self.permalink ||= build_permalink
  end

  def build_permalink
    date.strftime("%Y/%-m/") + title.parameterize("-")
  end

  def rebuild_preview
    Preview.new(self).rebuild
  end
end
Enter fullscreen mode Exit fullscreen mode

The first thing that comes to mind is to test callbacks directly with send. Please don't do so. It is private methods which are subject to change.

Instead it'd be better to test the public interface which uses those callbacks (before or after save → #save):

describe "#save"
  context "when permalink is NOT set" do
    it "generates it from year, month and title" do
      post = Post.create(
        date: new Date(2016, 07, 07),
        title: "Hello, its me")

      expect(post.permalink).to eq "2016/7/hello-its-me"
    end
  end

  context "when permalink is set" do
    it "preserves it" do
      post = Post.new(
        title: "Some title",
        permalink: "some-special-post")

      expect { post.save }.not_to change { post.permalink }
    end
  end

  if "rebuilds preview" do
    preview = instance_double(Preview, rebuild: true)
    post = Post.new(title: "Some title")
    allow(Preview).to receive(:new).and_return(preview)

    post.save

    expect(preview).to have_received(:rebuild)
  end
end
Enter fullscreen mode Exit fullscreen mode

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →