sconover / wrong

Wrong provides a general assert method that takes a predicate block. Assertion failure messages are rich in detail.
MIT License
433 stars 30 forks source link

Including Wrong in a Rails App #19

Open tjschuck opened 12 years ago

tjschuck commented 12 years ago

I'm having issues including Wrong in a trivial greenfield test application. Though this is more "support" than "issue", I'm guessing whatever the right answer is means the docs need updating.

First, get set up:

$ rails -v
Rails 3.2.3
$ rails new test_app
$ cd test_app/
$ rake db:create
$ rails g scaffold Post title:string body:text
$ rake db:migrate

This will give you a trivial new app with some tests to run:

$ rake test:functionals
Run options: 

# Running tests:

.......

Finished tests in 0.154397s, 45.3377 tests/s, 64.7681 assertions/s.

7 tests, 10 assertions, 0 failures, 0 errors, 0 skips

Okay, great. Now add gem "wrong" to the Gemfile, and bundle install.

Then, add wrong to your test/test_helper.rb file like so: https://gist.github.com/61af0b2b0431e61c1258

Crack open your test/functional/posts_controller_test.rb and add two trivial wrong-style assertions: https://gist.github.com/e75c14cf155e5decdf22

Now run your tests and enjoy your errors:

$ rake test:functionals

# Running tests:

...EE..

Finished tests in 0.160737s, 43.5494 tests/s, 62.2134 assertions/s.

  1) Error:
test_should_get_index(PostsControllerTest):
ArgumentError: wrong number of arguments (0 for 1)
[...]

  2) Error:
test_should_get_new(PostsControllerTest):
ArgumentError: wrong number of arguments (0 for 1)
[...]

7 tests, 10 assertions, 0 failures, 2 errors, 0 skips

The suite is seemingly still trying to use MiniTest's assert, which takes 1 argument.

Thoughts?

tjschuck commented 12 years ago

Additionally, things seem to be working okay in the Rails console:

$ rails c test
Loading test environment (Rails 3.2.3)
> assert { true }
NoMethodError: undefined method `assert' for main:Object
> require 'wrong/adapters/minitest'
=> true
> include Wrong
=> Object
irb(main):004:0> assert { true }
=> nil
alexch commented 12 years ago

Thanks for the detailed report. I'm looking into it now.

alexch commented 12 years ago

Looks like somewhere along the line Rails is including Test::Unit::Assertions into its ActionController::TestCase, even though ultimately it's a MiniTest::Unit::TestCase (with MiniTest::Unit::Assertions to boot). So testunit is overriding wrong's override of minitest's assert. I'll have to dig into the Rails code base to see what's up with that.

alexch commented 12 years ago

Looks like I'm going to have to rework the whole adapter system so that it can differentiate between raw minitest and minitest inside Rails.

In the meantime a workaround is to not do "require 'wrong/adapters/minitest'" and instead just put this in your test_helper.rb:

class ActiveSupport::TestCase
  # ...
  include Wrong
end

The problem with that workaround is that failures will be tallied as errors (since it won't be using the right exception class).