Reputation: 5178
According to the spec section within the minitest docs: the gem allows you to either use the "unit_test" syntax of testing or the "spec style" syntax of testing.
In my rails app: I have two tests on a scope within my model (note: I am using factory_girl to build objects within my tests). The following is, as I understand it, the typical way of writing tests with minitest within the context of rails:
# test/models/city_test.rb
require 'test_helper'
class CityTest < ActiveSupport::TestCase
test ".with_active_schools should return none" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city2)
create(:sequenced_inactive_school, city: city2)
assert_equal(0, City.with_active_schools.size)
end
test ".with_active_schools should return all" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city2)
create(:sequenced_active_school, city: city2)
assert_equal(2, City.with_active_schools.size)
end
end
I then run rails test test/models/city_test.rb
and all tests pass.
Now I want to see if it is possible to convert the above tests to the spec-style syntax. I comment out everything above in the same file. I then replace it with this code:
# test/models/city_test.rb
require 'test_helper'
describe City do
describe ".with_active_schools" do
it "returns no cities with active schools" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city2)
create(:sequenced_inactive_school, city: city2)
expect(City.with_active_schools.size).to eq(0)
end
it "returns cities with active schools" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city2)
create(:sequenced_active_school, city: city2)
expect(City.with_active_schools.size).to eq(2)
end
end
end
I then attempt to run the tests: rails test test/models/city_test.rb
, however it errors out:
undefined method `describe' for main:Object (NoMethodError)
I am not sure why it is throwing this error when the minitest docs says it supports this syntax. I did look at the rails guides for testing, but there is little content within the model testing section.
Upvotes: 6
Views: 2688
Reputation: 8630
You have to require 'minitest/spec'
to make the describe
function available.
Upvotes: 3
Reputation: 5178
I got the spec-style functioning, though the original question as to: "Why spec style syntax tests don't work out of the box with minitest in rails" is still unanswered. Hopefully someone might know and provide an answer.
What I had to do was load in the minitest-spec-rails gem:
#Gemfile
group :development, :test do
gem 'minitest-spec-rails', '~> 5.4'
end
Then I just had to convert to the MiniTest::Spec assertion syntax. It appears that the rspec matchers syntax will not work:
#test/models/city_test.rb
describe City do
describe ".with_active_schools" do
it "has no cities have active schools" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city1)
create(:sequenced_inactive_school, city: city2)
create(:sequenced_inactive_school, city: city2)
City.with_active_schools.size.must_equal(0)
end
it "has all cities have active schools" do
city1 = create(:sequenced_city)
city2 = create(:sequenced_city)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city1)
create(:sequenced_active_school, city: city2)
create(:sequenced_active_school, city: city2)
City.with_active_schools.size.must_equal(2)
end
end
end
And now it works when I run rails test test/models/city_test.rb
.
Upvotes: 3