如果我们要写rails测试,那么mock可少不了。很多测试需要模拟一个特殊环境,比如需要当前时间是下午几点几点才能;或者需要访问一个外部api以获取某些特定数据。如果单纯为了测试而去改代码肯定是行不通的,那么我们就需要用到mock测试了。
mock测试就是在测试过程中,对于某些不容易构造或者 不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。
mocha是rails测试中使用到的一个轻便的gem
https://github.com/freerange/mocha 按照文档,简单安装配置好就可以在测试里用上了。
一个简单的测试:
t = Time.parse('2015-10-11 14:00')
Time.expects(:now).returns(t)
assert_equal t , Time.now
而用stubs也同样可以
t = Time.parse('2015-10-11 14:00')
Time.stubs(:now).returns(t)
assert_equal t , Time.now
经过试验发现,如果expects指定的了方法,那么这次单元测试的过程中必须并且只用到一次这个方法
如果在第一块代码中间加一个puts Time.now 那么测试就会过不了,提示:
unsatisfied expectations:- expected exactly once, invoked twice: Time.now(any_parameters)
也就是说,而stubs则不会有这个问题,stubs一个方法,不管在后面的测试里有没有被用到,都不有问题
同时expects后面可以跟一些方法Time.expects(:now).returns(t).at_least_once表示期望now这个方法至少被调用一次……
看了下源代码,expects方法注释:
Adds an expectation that the specified method must be called exactly once with any parameters.
The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
stubs:
Adds an expectation that the specified method may be called any number of times with any parameters.
The original implementation of the method is replaced during the test and then restored at the end of the test. The temporary replacement method has the same visibility as the original method.
原来只是一个检验调用次数,一个不校验 - -
还有个用法 User.any_instance.stubs(……).returns(……)
,原理一样,都是对mock方法的封装,也不用管mock和stub的区别了,很方便。
感觉rails写到后面就是找各种gem来用……哪个方便用哪个啊