无法编写测试以验证我的连接表中的值的唯一性

时间:2016-07-05 15:00:04

标签: ruby-on-rails ruby validation activerecord rspec

不久之前,我找到了一个关于如何在我的连接表中创建唯一性验证的solution

class Album < ApplicationRecord
  has_many :album_artists
  has_many :artists, through: :album_artists
end

class AlbumArtist < ApplicationRecord
  belongs_to :album
  belongs_to :artist

  validate :uniqueness_of_album_artist

  private
    def uniqueness_of_album_artist
      if self.artist.albums.where(name: self.album.name).any?
        album.errors[:base] << "Artist already has an album by this name"
      end
    end
end

class Artist < ApplicationRecord
  has_many :album_artists
  has_many :albums, through: :album_artists
end

我现在想为我的AlbumArtist's uniqueness_of_album_artist验证程序编写测试。这就是我想出的:

it 'validates that album is unique to artist' do
  artist = FactoryGirl.create(:artist)
  artist.albums.push(FactoryGirl.create(:album, name: "Test"), FactoryGirl.create(:album, name: "Test"))

  album_artist = artist.album_artists.last

  expect(album_artist).to be_invalid
  expect(album_artist.errors[:base]).to include('Artist already has an album by this name')
end

奇怪的是,我的测试失败了:

Failure/Error: expect(album_artist).to be_invalid
       expected `#<AlbumArtist id: 2, artist_id: 1, album_id: 2, created_at: "2016-07-05 14:57:13", updated_at: "2016-07-05 14:57:13">.invalid?` to return true, got false

我继续前进并在此之后做了一些调试但是当我测试艺术家是否有两个同名的专辑时,它会返回true,从而证明它无效。

p artist.album_artists.first.album.name == artist.album_artists.last.album.name # returns true

这里发生了什么?

1 个答案:

答案 0 :(得分:0)

您的测试失败,因为artist_album有效。发生的事情是,由于您的验证,最后一个永远不会创建,但是当它失败时它不会被提升。试试这个:

it 'validates that album is unique to artist' do
  artist = FactoryGirl.create(:artist)
  album = FactoryGirl.create(:album)
  valid_artist_album = AlbumArtist.create(artist: artist, album: album)
  invalid_album_artist = AlbumArtist.new(artist: artist, album: album)

  expect(invalid_album_artist).to be_invalid

end

我正在编辑此帖子以使用代码突出显示。所以,如果你这样做:会发生什么?

it 'validates that album is unique to artist' do
  artist = FactoryGirl.create(:artist)
  album = FactoryGirl.create(:album)
  AlbumArtist.create!(artist: artist, album: album)
  invalid_album_artist = AlbumArtist.create!(artist: artist, album: album)

  expect(invalid_album_artist).to be_invalid

end

会发生什么?如果您将其设置为期望行,则验证无效。如果您在第二次创建时引发异常,那么您的验证工作正常。我认为,既然你说早期的测试表明invalid_album_artist实际上是有效的,你的验证不起作用,但改变你的测试将确认这一点。

相关问题