我非常喜欢开拓者的所有面向对象的美!
我有一个与gem(称为cpanel_deployer
)交互的操作,可以在Web上进行外部操作。 (它为cpanel添加了一个插件域。)
class Website::Deploy < Trailblazer::Operation
attr_reader :website, :cpanel
def process(params)
real_cpanel_add_domain
website.cpanel = cpanel
website.save
end
private
def setup!(params)
@cpanel = Cpanel.find(params[:cpanel_id])
@website = website.find(params[:website_id])
end
def real_cpanel_add_domain
cp_domain = CpanelDeployer::Domain.new(website.domain)
cp_panel = CpanelDeployer::Panel.new(cpanel.host, cpanel.username, cpanel.password)
res = cp_panel.add_domain(cp_domain)
raise StandardError unless res
end
end
cpanel_deloyer
宝石已经过测试,所以我不需要在这里重新测试它的功能。但是为了测试操作,我想确保使用正确的args调用CpanelDeployer::Panel#add_domain
。所以我想我应该嘲笑CpanelDeployer::Panel
。
我认为尝试使用any_instance_of
是不好的做法。根据思想机器人,它通常被认为是代码味道...他们建议使用依赖注入。是否有一种在开拓者操作中使用依赖注入的好方法?对于这种情况,还有另一种最佳做法吗?
答案 0 :(得分:0)
一个选项是在gem的类上存根:new
并返回测试双精度数。这是什么样的:
describe Website::Deploy do
let(:cpanel) { Cpanel::Create.(cpanel: {
host: 'cpanel-domain.com', username: 'user', password: 'pass'
}).model }
let(:website) { Website::Create.(website: { domain: 'domain.com' }).model }
it 'works' do
fake_cp_domain = double(CpanelDeployer::Domain)
fake_cp = double(CpanelDeployer::Panel)
expect(fake_cp).to receive(:add_domain).with(fake_cp_domain).and_return(true)
expect(CpanelDeployer::Domain).to receive(:new)
.with(website.domain)
.and_return(fake_cp_domain)
expect(CpanelDeployer::Panel).to receive(:new)
.with(cpanel.host, cpanel.username, cpanel.password)
.and_return(fake_cp)
Website::Deploy.(cpanel_id: cpanel.id, website_id: website.id)
end
end
这看起来很麻烦......有更好的方法吗?
答案 1 :(得分:0)
老实说,我真的不明白real_cpanel_add_domain
正在做什么,因为在我看来,它只是分配了两个局部变量,然后在其中一个上调用add_domain
,这对它会有什么影响?
谈到依赖注入,我想你可以从params
获取域和面板类,默认为CpanelDeployer::Domain
和CpanelDeployer::Panel
,但在你的规范中传递一些存根。
我不喜欢使用new
方法,因为它并不总是按预期工作。