如何在Minitest中Stub带参方法并验证参数传递
校验Minitest中Stub方法的参数
嘿,刚好我也经常用Minitest处理这类场景,你现在的测试已经能跑通,但要校验notify_exception的参数其实很简单,有两种常用的方法可以实现:
方法一:使用Minitest内置的Mock对象(推荐,更严谨)
Minitest自带的Minitest::Mock可以帮你明确设置方法调用的期望,包括参数和调用次数,最后还能验证这些期望是否被满足。修改你的测试代码如下:
test "should return bonsai_site_configuration even on exception and call notify_exception with correct exception" do site = Site.first # 先定义我们要抛出的异常,方便后续校验 expected_exception = StandardError.new('boom') # 创建Mock对象,期望notify_exception被调用1次,参数是我们定义的异常 exception_mock = Minitest::Mock.new exception_mock.expect(:call, nil, [expected_exception]) Site.stub(:all, [site]) do # 这里直接让bonsai_desc抛出我们预定义的异常,而不是动态生成 site.stub(:bonsai_desc) { raise expected_exception } do # 用Mock对象来Stub notify_exception方法 Site.stub(:notify_exception, exception_mock) do bonsai_information = Site.bonsai_site_configuration assert_equal(0, bonsai_information[:data].count) end end end # 验证Mock的期望是否被满足:notify_exception确实被传入正确参数调用了 exception_mock.verify end
这种方法的好处是,如果notify_exception没有被调用,或者调用时参数不对,mock.verify会直接让测试失败,能帮你确保业务逻辑里的异常通知逻辑确实触发了。
方法二:用变量捕获Stub方法的参数(更简洁)
如果你不需要严格验证方法是否被调用,只是想看看参数对不对,可以用一个变量来捕获notify_exception的入参:
test "should return bonsai_site_configuration even on exception and call notify_exception with correct exception" do site = Site.first captured_exception = nil expected_exception = StandardError.new('boom') Site.stub(:all, [site]) do site.stub(:bonsai_desc) { raise expected_exception } do # 给notify_exception的Stub传入一个block,接收参数并存到变量里 Site.stub(:notify_exception) do |exception| captured_exception = exception end do bonsai_information = Site.bonsai_site_configuration assert_equal(0, bonsai_information[:data].count) end end end # 校验捕获到的异常是否符合预期 assert_not_nil captured_exception, "notify_exception was not called" assert_equal(expected_exception.message, captured_exception.message) assert_instance_of(StandardError, captured_exception) end
这种方法代码更短,适合快速验证参数,但需要额外加assert_not_nil来确保方法确实被调用了,不然如果业务逻辑里没触发异常,测试可能会误过。
另外提个小细节:你原来的代码里用-> { raise 'boom' }抛出的是RuntimeError,而业务代码里rescue的是StandardError(RuntimeError是它的子类),所以没问题,但如果要更精准匹配,最好抛出和rescue一致的异常类型哦。
内容的提问来源于stack exchange,提问作者Ratatouille
相关产品推荐
相关产品推荐

