i try to create internet shop from "Agile Web Development with Rails 4". When i write 'rake test', i get this message:
$ rake test
Run options: --seed 54737
# Running:
........F...F
Finished in 0.279167s, 46.5671 runs/s, 118.2088 assertions/s.
1) Failure:
ProductTest#test__product_is_not_valid_without_a_unique_title_-_i18n [/Users/roni/Coding/Ruby/depot/test/models/product_test.rb:82]:
--- expected
+++ actual
## -1 +1 ##
-["translation missing: en.activerecord.errors.messages.taken"]
+["has already been taken"]
2) Failure:
ProductTest#test_product_price_must_be_positive [/Users/roni/Coding/Ruby/depot/test/models/product_test.rb:25]:
Failed assertion, no message given.
13 runs, 33 assertions, 2 failures, 0 errors, 0 skips
It's product_test.rb
http://pastebin.com/1f5zkDwa
Please, help me, what i did wrong?
It appears the location of error messages for the 'already taken' case has been changed in Rails 4 and the book must have missed this update.
The error message has been moved to the namespace where also other validation error messages of ActiveModel reside, to the errors.messages. Hence, the 'taken' error message was set under key activerecord.errors.messages.taken, but in Rails 4 it is under errors.messages.taken.
If you update line 82 in your test with the new key, the test should pass.
Just like the message states, you don't have translation for en.activerecord.errors.messages.taken in config/locales.
Also, in assert_equal method, first argument is actual value, while second argument is expected value. So it should be:
assert_equal product.errors[:title], ["has already been taken"]
in this case.
Related
I'm trying to send an email with Delayed::Job in Rails 5 like so: UserMailer.delay.test("my message", "email#example.com"). Unfortunately, it doesn't work. It gives this error:
FAILED (0 prior attempts) with ArgumentError: unknown command 'h'
or, sometimes,
FAILED (0 prior attempts) with NoMethodError: undefined methoddeliver' for false:FalseClass`
The stack trace is pretty cryptic.
I can run other methods asynchronously by appending handle_asynchronously :some_method after any method.
And UserMailer.test("my message", "email#example.com").deliver_now works fine. How can I debug this issue? Is my syntax wrong?
It's because my UserMailer method was named test, which doesn't seem to work in Delayed::Job
I am working on the Michael Hartl tutorial. When running my test, I get the following failure:
1) Failure:
SessionsHelperTest#test_current_user_returns_right_user_when_session_is_nil
[/home.../myapplication/test/helpers/sessions_helper_test.rb:11]:
--- expected
+++ actual
## -1 +1 ##
-#<User id:... >
+nil
Could anyone help make sense of this failure especially the following:
--- expected
+++ actual
## -1 +1 ##
Is there any official documentation from rails that gives guidance on those find of failure message? I have not found any. Thanks.
I do not know this tutorial and I don't know almost nothing of test but I think you have a error in your app. You get a nil output +nil and the expected output is a User element -#<User id:... >
Maybe you have wrong User.where clause
If you put more info I can try help more
My problem was that I had def current_user twice in app/helpers/sessions_helper.rb and one of them was outdated.
describe Item do
it 'calculates price according to a special formula' do
item = Item.new('kettle', price: 200)
item.price.should == 212
end
end
Deprecation Warnings:
Using should from rspec-expectations' old :should syntax without explicitly enabling the syntax is deprecated. Use the new :expect syntax or explicitly enable :should with
config.expect_with(:rspec) { |c| c.syntax = :should } instead. Called from E:/work/storeapp/spec/item_spec.rb:9:in `block (2 levels) in '.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
config.raise_errors_for_deprecations!, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 0.00505 seconds (files took 0.17058 seconds to load)
1 example, 0 failures
How this warning can be avoided?
Write the test in a new style:
expect(item.price).to eq 212
BTW. it seems you might doing sth quite risk/confusing. Once you assign 200 to the attribute, it will be more than confusing to see another value returned by a getter with a same name. Have you considered leaving the original method alone and defining a new one instead (like price_with_vat)?
When I log into my ruby applicaiton, the first page url is http://localhost:3000/tree_display/list. So , when I run the test to assert the same, I am getting this error.
[user1 project]$ rake test
DEPRECATION WARNING: String based terminators are deprecated, please use a lambda. (called from included at /home/.gem/ruby/2.1.3/bundler/gems/authlogic-09163c7d2a9b/lib/authlogic/session/callbacks.rb:66)
DEPRECATION WARNING: String based terminators are deprecated, please use a lambda. (called from included at /home/.gem/ruby/2.1.3/bundler/gems/authlogic-09163c7d2a9b/lib/authlogic/session/callbacks.rb:67)
Started
FAIL["test_login_and_access_bookmarks/managing_bookmarks", BookmarksTest, 0.678676891]
test_login_and_access_bookmarks/managing_bookmarks#BookmarksTest (0.68s)
expecting <"tree_display/list"> but rendering with <["content_pages/view", "shared/_header", "shared/_navigation", "auth/_login", "shared/_flash_messages", "shared/_footer_message", "layouts/application"]>
test/integration/bookmarks_test.rb:15:in `block in <class:BookmarksTest>'
1/1: [=========================================================================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.68149s
1 tests, 2 assertions, 1 failures, 0 errors, 0 skips
[user1 project]$
It is rendering with <["content_pages/view", "shared/_header", "shared/_navigation", "auth/_login", "shared/_flash_messages", "shared/_footer_message", "layouts/application"]>. These are supposed to be on the first page when I enter the username and password and then I go to http://localhost:3000/tree_display/list
I noticed that the session variable contains this :#host="www.example.com",
What is the problem here? Why is it not rendering the tree_display/list? Appreciate any help.
Probably login failed in your test or it is taking time to login while you are asserting on previous page in the test. Try adding delays in assertion and login step.
This all worked fine in rails 2.3.5, but when a contractor firm upgraded directly to 2.3.14 suddenly all the integration tests were saying:
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
I have a before_filter on my ApplicationController that sets a bunch of cookies for some javascript to use, and I found that if I comment out all but one of the lines that sets cookie values, it works fine, and it doesn't matter which line I leave in.
before_filter :set_cookies
def set_cookies
cookies['logged_in'] = (logged_in ? 'y' : 'n')
cookies['gets_premium'] = (gets_premium ? 'y' : 'n')
cookies['is_admin'] = (is_admin ? 'y' : 'n')
end
If only one of these lines is active, everything is fine in the integration test, otherwise I get the error above. For example, consider the following test / response:
test "foo" do
get '/'
end
$ ruby -I"lib:test" test/integration/foo_test.rb -n test_foo -v
Loaded suite test/integration/foo_test
Started
test_foo(FooTest): E
Finished in 5.112648 seconds.
1) Error:
test_foo(FooTest):
NoMethodError: You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.[]
test/integration/foo_test.rb:269:in `test_foo'
1 tests, 0 assertions, 0 failures, 1 errors
But if any two of those cookie setting lines are commented out, I get:
$ ruby -I"lib:test" test/integration/foo_test.rb -n test_foo -v
Loaded suite test/integration/foo_test
Started
test_foo(FooTest): .
Finished in 1.780388 seconds.
1 tests, 0 assertions, 0 failures, 0 errors
The website running in development and production mode works fine - this is just a matter of getting the tests passing. Also, with debugging output I have verified that the error does not get thrown in the method where the cookies get set, that all executes fine, it's somewhere later that the error happens (but the backtrace doesn't tell me where)
This turned out to be a bug in how rack rack writes cookies to the client along with the session cookie. Rack was including double newlines and omitting semi-colons.
Browsers like firefox can handle mildly malformed cookie data, but the integration test client couldn't.
To fix this I had to rewrite the cookie header before sending it to the client.
In environment.rb:
require 'rack_rails_cookie_header_hack'
And in lib/rack_rails_cookie_header_hack.rb:
class RackRailsCookieHeaderHack
def initialize(app)
#app = app
end
def call(env)
status, headers, body = #app.call(env)
if headers['Set-Cookie']
cookies = headers['Set-Cookie']
cookies = cookies.split("\n") if is_str = cookies.is_a?(String)
if cookies.respond_to?(:collect!)
cookies.collect! { |h| h.strip }
cookies.delete_if { |h| h.empty? }
cookies.collect! { |h| h.include?(';') ? h : h + ';' }
end
headers['Set-Cookie'] = is_str ? cookies.join("\n").strip : cookies
end
[status, headers, body]
end
end
Sorry the sources aren't articulated, I actually fixed this awhile ago and came across this questions and figured I'd post my patch.
L0ne's answer works for me, but you also need to include this - it can go at the bottom of lib/rack_rails_cookie_header_hack.rb, providing you're requiring it at the bottom of your environment.rb file - ie after the Rails::Initializer has run:
ActionController::Dispatcher.middleware.insert_before(ActionController::Base.session_store, RackRailsCookieHeaderHack)
Old forgotten issues...
I haven't tested Lone's fix but he has correctly identified the problem. If you catch the exception and print using exception.backtrace, you'll see that the problem is caused by
gems/actionpack/lib/action_controller/integration.rb:329
The offending code is this:
cookies.each do |cookie|
name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
#cookies[name] = value
end
If you're like me, and you're only interested in some super quick integration tests, and don't care too much about future maintainability (since it's rails 2), then you can just add a conditional filter in that method
cookies.each do |cookie|
unless cookie.blank?
name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
#cookies[name] = value
end
end
and problem solved