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
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
Top comments (0)