I am new to testing. I am trying to use stripe-ruby-mock gem with minitest.
In the stripe-ruby-mock docs they describe a dummy example in Rspec that I am trying to translate to minitest:
require 'stripe_mock'
describe MyApp do
let(:stripe_helper) { StripeMock.create_test_helper }
before { StripeMock.start }
after { StripeMock.stop }
it "creates a stripe customer" do
# This doesn't touch stripe's servers nor the internet!
customer = Stripe::Customer.create({
email: 'johnny#appleseed.com',
card: stripe_helper.generate_card_token
})
expect(customer.email).to eq('johnny#appleseed.com')
end
end
My translation to minitest
require 'test_helper'
require 'stripe_mock'
class SuccessfulCustomerCreationTest < ActionDispatch::IntegrationTest
describe 'create customer' do
def stripe_helper
StripeMock.create_test_helper
end
before do
StripeMock.start
end
after do
StripeMock.stop
end
test "creates a stripe customer" do
customer = Stripe::Customer.create({
email: "koko#koko.com",
card: stripe_helper.generate_card_token
})
assert_equal customer.email, "koko#koko.com"
end
end
end
The error
NoMethodError: undefined method `describe' for SuccessfulPurchaseTest:Class
I consulted the minitest docs to make sure describe wasn't specific to Rspec but it turns out it is also used in minitest. I am guessing the implementation isn't done properly. Any help appreciated.
Hi I'm mostly an Rspec guy but I think you're issue is that you are using and integration test case when you should be using an unit test case. Try the following instead
class SuccessfulCustomerCreationTest < MiniTest::Unit::TestCase
I think you are mixing things. Check Minitest page on sections Unit tests and Specs.
I think what you need is the following:
require 'test_helper'
require 'stripe_mock'
class SuccessfulCustomerCreationTest < Minitest::Test
def stripe_helper
StripeMock.create_test_helper
end
def setup
StripeMock.start
end
def teardown
StripeMock.stop
end
test "creates a stripe customer" do
customer = Stripe::Customer.create({
email: "koko#koko.com",
card: stripe_helper.generate_card_token
})
assert_equal customer.email, "koko#koko.com"
end
end
Or if you want use the Spec syntax. Hope this helps someone.
you want to require:
require 'spec_helper'
for rspec example.
Related
I'm having trouble getting the Clearance authentication to work with Rails controller unit testing. I've followed the instructions at https://github.com/thoughtbot/clearance "Controller Test Helpers". How do you unit test controllers that require authentication?
I get the following error:
GoalsControllerTest#test_should_get_index:
NoMethodError: undefined method `sign_in_as' for #<GoalsControllerTest:0x007f8c41c6b9c8>
test/controllers/goals_controller_test.rb:7:in `block in <class:GoalsControllerTest>'
test/test_helper.rb
require 'clearance/test_unit'
test/controller/goals_controller_test.rb
require 'test_helper'
class GoalsControllerTest < ActionDispatch::IntegrationTest
setup do
user = User.new(fname: "Test", lname: "User", email: "testuser#test.com", password: "password")
sign_in_as(user)
#goal = goals(:one)
end
i've same problem with you, but now fixed by this answer https://github.com/thoughtbot/clearance/issues/695
Enable the Middleware in Test:
# config/environments/test.rb
MyRailsApp::Application.configure do
# ...
config.middleware.use Clearance::BackDoor
# ...
end
In my test/test_helper.rb file, I wrote this following code.
class ActionDispatch::IntegrationTest
def manual_sign_in_as(user)
post session_url, params: {
session: {
email: user.email,
password: user.password
}
}
end
end
Rails 5 subclasses controller tests from ActionDispatch::IntegrationTest by default, so I only had to follow the instructions on the readme from here https://github.com/thoughtbot/clearance.
class PostsControllerTest < ActionDispatch::IntegrationTest
test "user visits index page while logged in"
user = User.create!(email: "example#example.com", password: "letmein")
get links_url(as: user)
# and
post links_url(as: user), params: { post: { title: "hi" } }
end
end
Are you using Rails 5? Rails 5 unified integration and controller tests behind ActionDispatch::IntegrationTest. When you require clearance/test_unit, Clearance is only adding it's helpers to ActionController::TestCase.
I think you could do:
class ActionDispatch::IntegrationTest
include Clearance::Testing::ControllerHelpers
end
in your test_helper.rb file in order to get access to the helpers in those tests. However, I'm not certain the helpers themselves will work in that context.
If you could give that a try, it'd be helpful. This should be fixed in Clearance as well. Since I don't use TestUnit/MiniTest myself I sometimes miss things like this.
I have a PostDecorator class in app/decorators/post_decorator.rb.
It has a method that calls Devise's current_user method. It looks like this:
class PostDecorator < Draper::Decorator
delegate_all
def voter
h.current_user
end
end
I have a PostDecorator spec in spec/decorators/post_decorator_spec.rb
require 'spec_helper'
describe PostDecorator, type: :decorator do
let(:post) { FactoryGirl.create(:post) }
let(:user) { FactoryGirl.create(:user) }
before { allow(helper).to receive(:current_user) { user } }
describe 'voter' do
it 'returns the current_user' do
expect(post.voter).to eq user
end
end
end
When I run this I get an undefined method error:
<Draper::HelperProxy:0x007fb1c4f85890 ... does not implement: current_user
Gem Versions:
draper (1.4.0)
rspec-rails (3.4.1)
devise (3.5.5)
Also I should note everything in my app/lib directory is auto loaded. In application.rb I have config.autoload_paths << Rails.root.join('lib')
Two things I think you need to do.
1.) Add devise test helpers to your decorator tests,
RSpec.configure do |config|
config.include Devise::TestHelpers, type: :decorator
end
2.) you actually need to sign_in to expect post.voter to eq an actual users
require 'spec_helper'
describe PostDecorator, type: :decorator do
let(:post) { FactoryGirl.create(:post) }
let(:user) { FactoryGirl.create(:user) }
before do
sign_in user
end
describe '.voter' do
it 'returns the current_user' do
expect(post.voter).to eq user
end
end
end
The issue is related to Draper.
Decorator is unable to access helper methods after sending an ActionMailer email.
This is an open issue on Draper's GitHub
To solve this I just modified the User Factory by adding a confirmed_at:
factory :user do
...
confirmed_at DateTime.now
end
This way Devise won't send a Confirmation email.
Now I use rr gem to stub Project model count method, and then I replicate index action to check the count method is called or not. I'm planning to use mocha gem but I don't figure out what is the equivalent of assert_received method in mocha gem. Following code is one of the example of my tests.
require 'test_helper'
class ProjectsControllerTest < ActionController::TestCase
context "on GET to index" do
setup do
stub(Project).count { 30000 }
get :index
end
should "load up the number of gems, users, and downloads" do
assert_received(Project) { |subject| subject.count }
end
end
end
require 'test_helper'
class ProjectsControllerTest < ActionController::TestCase
context "on GET to index" do
setup do
Project.stubs(:count).returns(30000)
end
should "load up the number of gems, users, and downloads" do
Project.expects(:count).returns(30000)
get :index
end
end
end
Hope this can help, and here is the mocha API.
RSpec has:
describe "the user" do
before(:each) do
#user = Factory :user
end
it "should have access" do
#user.should ...
end
end
How would you group tests like that with Test::Unit? For example, in my controller test, I want to test the controller when a user is signed in and when nobody is signed in.
You can achieve something similar through classes. Probably someone will say this is horrible but it does allow you to separate tests within one file:
class MySuperTest < ActiveSupport::TestCase
test "something general" do
assert true
end
class MyMethodTests < ActiveSupport::TestCase
setup do
#variable = something
end
test "my method" do
assert object.my_method
end
end
end
Test::Unit, to my knowledge, does not support test contexts. However, the gem contest adds support for context blocks.
Shoulda https://github.com/thoughtbot/shoulda although it looks like they've now made the context-related code into a separate gem: https://github.com/thoughtbot/shoulda-context
Using shoulda-context:
In your Gemfile:
gem "shoulda-context"
And in your test files you can do things like (notice the should instead of test:
class UsersControllerTest < ActionDispatch::IntegrationTest
context 'Logged out user' do
should "get current user" do
get api_current_user_url
assert_response :success
assert_equal response.body, "{}"
end
end
end
I have a problem trying to use 'shoulda' with 'factory_girl' for creating a functional test for 'create' in a Rails application. I created a simple project, scaffolded user, added 'shoulda' (current gem version on my system 2.11.3 ) and 'factory_girl' in test_helper.rb. Creating the user manually works fine. Following are the steps to reproduce the failure :
rails project
scaffold user name:string
add in test_helper.rb :
require 'shoulda'
require 'factory_girl'
rake db:migrate
write the following functional test for user (override users_controller_test.rb ) :
class UsersControllerTest < ActionController::TestCase
Factory.define(:user) do |u|
u.name 'joe'
end
context "should create user" do
context "with valid data" do
setup do
User.any_instance.expects(:save).returns(true).once
User.any_instance.stubs(:id).returns(1001)
post :create, :user => {}
end
should_assign_to :user, :class => User
should_set_the_flash_to "User was successfully created."
should_redirect_to("user page"){user_path(1001)}
end
end
end
Running the test with "rake test:functionals" shows failure :
Expected response to be a redirect to <http://test.host/users/1001> but was
a redirect to <http://test.host/users>.
I played also with "should redirect_to", because I saw "should_redirect_to" is deprecated,
but with no luck. Do you have any ideas ?
Thank you in advance,
Marian Vasile Caraiman.
Instead of stubbing User#id, stub User.create and use particular user mock object.
setup do
mock_user = Factory.stub(:user, :id => 1001)
User.expects(:create).returns(mock_user)
mock_user.expects(:save).returns(true)
post :create, :user => {}
end