2

I found that stackoverflow old post that suggests model_entity.send(:before_create) but now it doesn't work. So, how can I test method that should execute before create, update, destroy.There is another post but i can't figure out, what I should do in my case.

class User < ActiveRecord::Base

  before_create do |user|
    user.secure_token = UUID.new.generate
  end
end

The point is I can just make a method with this code, and call it. Is there any other ways?

In general, if I want to test after_create method, that only have in my model at all, I should create Model Object and check it. But, I guess, it's unnecessary actions. I could just check this method without creation any instances.

3 Answers 3

5

There's a dry way of doing this:

expect{ user.save }.to change{ user.secure_token }
Sign up to request clarification or add additional context in comments.

Comments

3

Just found something tricky. If you need to validate the actual result, validate that separately, because the current rspec doesn't pass the return value of the function :secure_token= if you use the .should_receive(:secure_token=). Example:

Model as above:

describe "verifies that secure_token= is called" do
  @user = User.new
  @user.should_receive(:secure_token=)
  @user.save
end

describe "verifies the result is set" do
  @user = User.new
  @user.save
  expect(@user.secure_token).not_to be_empty
end

But if you put the expect not to be empty in the same test as the should_receive, then the test will fail.

Comments

2

If you are using rspec, I'm guessing you can do:

@user = User.new
@user.should_receive(:secure_token)
@user.save

5 Comments

So, if it shouldn't receive it throws something? How can I form it as test. before(:each) do @user = User.new end it "should have a secure_token" do @user.should_receive(:secure_token) @user.save end
As an errors says, your test expects "during save your object is calling 'secure_token' method once", but somehow your code is calling this method two times. It looks like, there is some other callback method (in User object) which is setting secure_token on this object.
Yes, there is a validation. If it calls, so it does call twice.
So you can do two things: @user.should_receive(:secure_token).twice, or @user.save(:validate => false) (saving without validation)
shouldn't it be @user.should_receive(:secure_token=) note the =...?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.