[openstack-dev] [puppet] "stubs" considered harmful in spec tests
Rich Megginson
rmeggins at redhat.com
Thu Jun 4 16:34:22 UTC 2015
Summary - In puppet module spec tests, do not use "stubs", which means
the method will be called 0 or more times. Instead, use "expects",
which means the method must be called exactly 1 time, or some other more
fine grained expectation method stubber.
Our puppet unit tests mostly use rspec, but use Mocha
http://gofreerange.com/mocha/docs/index.html for object mocking and
method stubbing.
I have already run into several cases where the spec test result is
misleading because "stubs" was used instead of "expects", and I have
spent a lot of time trying to figure out why a method was not called,
because adding an expectation like
provider.class.stubs(:openstack)
.with('endpoint', 'list', '--quiet',
'--format', 'csv', [])
.returns('"ID","Region","Service Name","Service
Type","Enabled","Interface","URL"
"2b38d77363194018b2b9b07d7e6bdc13","RegionOne","keystone","identity",True,"admin","http://127.0.0.1:5002/v3"
"3097d316c19740b7bc866c5cb2d7998b","RegionOne","keystone","identity",True,"internal","http://127.0.0.1:5001/v3"
"3445dddcae1b4357888ee2a606ca1585","RegionOne","keystone","identity",True,"public","http://127.0.0.1:5000/v3"
')
implies that "openstack endpoint list" will be called.
If at all possible, we should use an explicit expectation. For example,
in the above case, use "expects" instead:
provider.class.expects(:openstack)
.with('endpoint', 'list', '--quiet',
'--format', 'csv', [])
.returns('"ID","Region","Service Name","Service
Type","Enabled","Interface","URL"
"2b38d77363194018b2b9b07d7e6bdc13","RegionOne","keystone","identity",True,"admin","http://127.0.0.1:5002/v3"
"3097d316c19740b7bc866c5cb2d7998b","RegionOne","keystone","identity",True,"internal","http://127.0.0.1:5001/v3"
"3445dddcae1b4357888ee2a606ca1585","RegionOne","keystone","identity",True,"public","http://127.0.0.1:5000/v3"
')
This means that "openstack endpoint list" must be called once, and only
once. For odd cases where you want a method to be called some certain
number of times, or to return different values each time it is called,
the Expectation class
http://gofreerange.com/mocha/docs/Mocha/Expectation.html should be used
to modify the initial expectation.
Unfortunately, I don't think we can just do a blanket
"s/stubs/expects/g" in *_spec.rb, without incurring a lot of test
failures. So perhaps we don't have to do this right away, but I think
future code reviews should -1 any spec file that uses "stubs" without a
strong justification.
More information about the OpenStack-dev
mailing list