8

I have a test double that I'd like to be able to receive any message.

I know I can expect the double to receive a certain message and return a value like so:

foo = double()
allow(foo).to receive(:bar) { "Foobar" }

I can also allow foo to receive any message using #as_null_object like:

foo = double()
foo.as_null_object

Is there any other syntax for this? Seems I should be able to do something like:

allow(foo).to receive(:anything)
jordelver
  • 8,292
  • 2
  • 32
  • 40

1 Answers1

3

allow and expect methods can be used to stub methods/set expectations on particular method. Augmenting object with null object pattern is quite different, and thus uses different method call.

Please note that you should usually not use null object in area that is tested by particular test -- it is meant to imitate some part of the system that is side effect of tested code, which cannot be stubbed easily.

samuil
  • 5,001
  • 1
  • 37
  • 44
  • 1
    Thanks. I am trying to allow any message on a collaborator, I don't care about what gets sent to it as I am testing another part of the code. Is `as_null_object` a good fit for that? – jordelver May 07 '14 at 08:24
  • Sure, it seems perfect application for null object pattern. This way your test does not have to be changed every time interface of object imitated with null object changes. Another approach for solving your problem would be usage of fixtures or factories, but as long as null object is enough it is a easier to implement and faster to run. – samuil May 07 '14 at 08:27
  • Yeah, I'm wondering whether to setup the default doubles in `let` blocks as Null objects and then only stub the particular methods that matter in individual tests, otherwise, as you say, lots of tests fail when changing the interface. I'm not sure what the best practice is? – jordelver May 07 '14 at 08:31
  • I would consider use of null object best practice where applicable. Sometimes you can encounter situations in which null object will cause code fed with it to fail (it will not return correct values when called). In that case you should consider using fixtures or factories (the latter being probably more versatile approach). – samuil May 07 '14 at 08:38