Juanma Cervera
2008-Apr-02 08:13 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
Hello I am learning rspec and trying to especify the activerecord validations of my models. How would I make a require_uniqueness_of specification for a field. Can I make this with mocks, without touching the database? Can somebody point me to some information or plugin for this issue. Thank you very much. Juan M. Cervera -- Posted via http://www.ruby-forum.com/.
IMO this function should be tested using the database, since it relies heavily on the data. ________________ Courtenay @(o..O)@ On Apr 2, 2008, at 1:13 AM, Juanma Cervera <lists at ruby-forum.com> wrote:> Hello > > I am learning rspec and trying to especify the activerecord > validations > of my models. > > How would I make a require_uniqueness_of specification for a field. > Can I make this with mocks, without touching the database? > Can somebody point me to some information or plugin for this issue. > > Thank you very much. > > Juan M. Cervera > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Pat Maddox
2008-Apr-02 08:58 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
On Wed, Apr 2, 2008 at 1:19 AM, Courtenay <court3nay at gmail.com> wrote:> IMO this function should be tested using the database, since it relies > heavily on the data.Agreed. Create a record, then create another record with duplicate data, and verify that the second record is invalid. Pat
Matt Berther
2008-Apr-03 06:14 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
Hi Juanma, I do this this way: describe Model do def create(options={}) Model.create(options) end it "should not allow duplicate names" do model = create(:name => "name") new_model = create(:name => "name") new_model.should have_error_on(:name, :taken) end end -- Matt Berther http://www.mattberther.com On Apr 2, 2008, at 2:13 AM, Juanma Cervera wrote:> Hello > > I am learning rspec and trying to especify the activerecord > validations > of my models. > > How would I make a require_uniqueness_of specification for a field. > Can I make this with mocks, without touching the database? > Can somebody point me to some information or plugin for this issue. > > Thank you very much. > > Juan M. Cervera > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
Juanma Cervera
2008-Apr-03 11:38 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
Thanks to all for your answers. I also have found a plugin with matchers for active record validations, associations and even useful matchers for views. It has a matcher for validates_uniqueness_of that doesn''t got to the database. The url is http://code.google.com/p/rspec-on-rails-matchers/ ?What do you think of using this plugin? Juanma Cervera. -- Posted via http://www.ruby-forum.com/.
On Thu, Apr 3, 2008 at 4:38 AM, Juanma Cervera <lists at ruby-forum.com> wrote:> Thanks to all for your answers. > I also have found a plugin with matchers for active record validations, > associations and even useful matchers for views. > > It has a matcher for validates_uniqueness_of that doesn''t got to the > database. >The test asserts that you call validates_uniqueness_of, but it doesn''t actually test your logic. So it''s useful to see if someone accidentally deletes your code, but if you have validates_uniqueness_of :user, :scope => :project_id or something more complex, it won''t test this behavior.
Steven Baker
2008-Apr-04 05:41 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
>> > The test asserts that you call validates_uniqueness_of, but it doesn''t > actually test your logic. > So it''s useful to see if someone accidentally deletes your code, but > if you have > > validates_uniqueness_of :user, :scope => :project_id > > or something more complex, it won''t test this behavior.One of the rules that I learned with TDD, that I brought with me to BDD, is that you only specify or test what you write. Everything else is assumed to behave as intended. This rule is, among other things, intended to keep us productive: we can''t write a test suite for an entire framework every time we use that framework to implement an application. At some point, we have to trust that the frameworky bits work as intended. I don''t exactly assume that the code I''m depending on is well tested, just that it''s not my job to specify its behaviour. If you were to write an example that creates two models, and ensures that the duplicate errored appropriately, my "rule" is violated. Each of your examples is then specifying the behaviour of the validates_uniqueness_of method, which you didn''t write. Doing this with mocks ensures that you called validates_uniqueness_of, and doesn''t test the behaviour of the method which, since you didn''t write it, get to assume behaves as expected. This is where my "rule" falls down: mocking the call prevents you from changing the implementation without changing the behaviour. That is to say that you may want to, in the future, roll your own uniqueness validation that is called in a different way than ActiveRecord''s, but behaves in the same way. If you mocked, you could change the implementation without changing the behaviour, and still have a failing example. This is where the line is drawn for me: I need to be able to change the implementation, and only have my examples fail when I''ve changed the behaviour. So, in this case, using mocks and expecting Rails'' built-in validation is fragile. But in general, I try to stick to the "rule" (let''s say guideline from now on) that I outlined above. -Steven
Pat Maddox
2008-Apr-04 06:02 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
On Thu, Apr 3, 2008 at 10:41 PM, Steven Baker <steven at stevenrbaker.com> wrote:> If you were to write an example that creates two models, and ensures > that the duplicate errored appropriately, my "rule" is violated. Each > of your examples is then specifying the behaviour of the > validates_uniqueness_of method, which you didn''t write.I don''t really agree with this. The desired behavior is to disallow two records with the same data. v_u_o is simply a quick and easy means to that end. Pat
Steven Baker
2008-Apr-04 06:12 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
>> If you were to write an example that creates two models, and ensures >> that the duplicate errored appropriately, my "rule" is violated. >> Each >> of your examples is then specifying the behaviour of the >> validates_uniqueness_of method, which you didn''t write. > > I don''t really agree with this. The desired behavior is to disallow > two records with the same data. v_u_o is simply a quick and easy > means to that end.Right. As I said (or intended to) that particular example was so simple that it was a grey area. But it did cause me to think about the problem, and I found it interesting. -Steven
Rick DeNatale
2008-Apr-04 11:31 UTC
[rspec-users] spec''ing validates_uniqueness_of :whatever
On Fri, Apr 4, 2008 at 2:12 AM, Steven Baker <steven at stevenrbaker.com> wrote:> >> If you were to write an example that creates two models, and ensures > >> that the duplicate errored appropriately, my "rule" is violated. > >> Each > >> of your examples is then specifying the behaviour of the > >> validates_uniqueness_of method, which you didn''t write. > > > > I don''t really agree with this. The desired behavior is to disallow > > two records with the same data. v_u_o is simply a quick and easy > > means to that end. > > Right. As I said (or intended to) that particular example was so > simple that it was a grey area. But it did cause me to think about > the problem, and I found it interesting.While I certainly subscribe to the "don''t test what you didn''t write" philosophy for the most part. I do think that there are gray areas. Quoting Steven from a bit earlier in this thread:> I don''t exactly assume that the code I''m depending on is well tested, > just that it''s not my job to specify its behavior.One of the gray areas is that despite all good intentions, sometimes the specification of that behavior isn''t entirely clear, even if that specification is written down somewhere as specs, or traditional documentation. Problems can creep in when my understanding doesn''t exactly match the writer''s intent. In these cases, it seems to me that writing a spec which proves that my interpretation of an interface by specifying the results rather than just the presence of the call, just MIGHT be a reasonable thing to do, and might protect against the possibility that the writer''s interpretation changes due either to evolution or a ''bug-fix.'' -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/