我开始学习如何模拟事物,因为对于有 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
调用 invokestatus()
吗?
如果不是,那么如果我不得不打电话给p.status
自己,那是不是p.public_url()
完全无视我写的逻辑,并严格遵循我在中定义的内容expects
?这对单元测试有什么帮助?也许我不明白嘲笑的目的。
更新:
根据@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
?)来存根一个帐户。我收到一个错误:undefined method 'full_domain' for Mocha::Expectation:
但我的夹具定义如下:
localhost:
id: 1
name: My first account
full_domain: test.domain.vhost
我设置了固定装置,这样我就可以拥有常用模型的基础知识,以便在我的所有测试中轻松使用。每个测试的标准模型/关系(如果我是手动/与工厂女孩一起进行测试,没有嘲笑,将需要:
Account
,Subscription
(has Account
,SubscriptionPlan
),,SubscriptionPlan
(User
属于Account
),AccountProperties
(has Account
),然后是实际的对象我在测试on,属于anAccount
和a User
on that Account
,每次测试都有点多。哈哈
更新 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
事实证明,您可以访问诸如accounts
或之类的固定装置users
。