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)