gpt4 book ai didi

ruby-on-rails - 使用 Mocha 进行模拟实际上如何让您测试函数中的逻辑?

转载 作者:数据小太阳 更新时间:2023-10-29 08:09:41 25 4
gpt4 key购买 nike

我开始学习如何模拟事物,因为对于具有 1000 多个测试的项目来说,使用 Factory Girl 并不是很实用。我不能在每次测试时都访问数据库,尤其是当我希望进行任何类型的自动化持续集成时。

我的测试:

    it "should return an URL with the desired security protocol" do
p = Proposal.new
p.expects(:status).returns(Proposal::PUBLISHED) #this should be invoked by public_url?
p.expects(:public_url).returns("https://something")
p.expects(:public_url).with(true).returns("https://something")
p.expects(:public_url).with(false).returns("http://something")
assert p.public_url.index("https") != nil
assert p.public_url(true).index("https") != nil
assert p.public_url(false).index("https") == nil
end

上述测试方法:

def public_url(https = true)
url = ""
if self.published?
# attepmt to find sluggable id
id = sluggable_id
url = (https ? "#{ENV['SSL_PROTOCOL']}://" : "http://") +
self.account.full_domain + "/view/" + id.to_s
end

return url
end

def published?
return self.status > UNPUBLISHED
end

但这是我运行测试时得到的结果:

unsatisfied expectations:
- expected exactly once, not yet invoked: #<Proposal:0x7fbd07e82a30>.status(any_parameters)

调用 public_url 不应该调用 status() 吗?

如果不是,那么如果我必须自己调用p.status,这是否意味着p.public_url() 完全忽略了我编写的逻辑,并严格遵循我在 expects 中定义的内容?这对单元测试有何帮助?可能我不明白mock的用意。


更新:

根据@Philip 的建议,我将我的测试更改为此,消除了对任何 ActiveRecord 恶作剧的需要:

    it "should return an URL with the desired security protocol" do
p = Proposal.new
p.expects(:id).returns(1)
p.expects(:status).returns(Proposal::PUBLISHED)
p.expects(:account).returns(Account.new.stubs(:localhost))

assert p.public_url.starts_with("https")
assert p.public_url(true).starts_with("https")
assert !p.public_url(false).starts_with("https")
end

我想现在我的问题是,如何使用固定装置(我命名为 localhost?) stub 帐户。我得到一个错误:undefined method 'full_domain' for Mocha::Expectation: 但我的 fixture 定义如下:

localhost:
id: 1
name: My first account
full_domain: test.domain.vhost

我设置了固定装置,这样我就可以拥有常用模型的基础知识,以便在我的所有测试中轻松使用。每次测试的标准模型/关系(如果我手动/与没有 mock 的工厂女孩​​一起进行测试,则需要这样:Account, Subscription(有Account, SubscriptionPlan), SubscriptionPlan, User(属于 Account)、AccountProperties(有 Account),然后是我正在测试的实际对象,属于一个Account 和那个Account 上的一个User,这对每个测试来说有点多。哈哈


更新 2:

成功了:

it "should return an URL with the desired security protocol" do
p = Proposal.new({:status => Proposal::PUBLISHED})
p.expects(:id).returns(1)
p.expects(:account).returns(accounts(:localhost)).times(3)

assert p.public_url.starts_with?("https")
assert p.public_url(true).starts_with?("https")
assert !p.public_url(false).starts_with?("https")
end

事实证明,您可以访问 accountsusers 等固定装置。

最佳答案

我对此的理解是,您的三个 p.expects(:public_url)... 行正在删除该方法并返回您告诉它返回的值。所以一旦你完成了你的方法体就永远不会被调用...... stub 已经接管了。因此...因为您告诉它也期待对 status 的调用,所以这永远不会发生。

查看您的代码...我认为您想要删除的是 self.account.full_domain 并且可能是 id.to_s 这一行:

url = (https ? "#{ENV['SSL_PROTOCOL']}://" : "http://") + 
self.account.full_domain + "/view/" + id.to_s

这将跳过任何 AR 关系内容,但仍会执行您方法中的其余条件。

另外..我会改变你的断言。下面还将匹配一个非安全 url,如“http://https.com/blahblah”,这不是你真正想要的。其他的也可以通过,但同样是出于无效原因。

assert p.public_url(true).index("https") != nil

所以也许是这样的:

assert p.public_url(true).starts_with("https://") true

或者,获取结果并使用 URI 解析它,然后直接测试方案(可能是矫枉过正的想法)

关于ruby-on-rails - 使用 Mocha 进行模拟实际上如何让您测试函数中的逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14178770/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com