2016-02-26 29 views
1

我很喜欢Trailblazer的所有面向对象的美丽!如何测试/模拟与外部宝石交互的开拓者操作?

我有一个操作可以与一个gem(叫做cpanel_deployer)交互,在网络上做一些外部事情。 (它增加了一个附加域到的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宝石已经测试过,所以我并不需要重新测试它的功能在这里。但为了测试操作,我想确保CpanelDeployer::Panel#add_domain以正确的参数被调用。所以我想我应该嘲笑CpanelDeployer::Panel

我认为尝试使用any_instance_of是不好的做法。根据thinkbot,它通常被认为是代码异味...他们推荐使用依赖注入。在开拓者操作中是否有使用依赖注入的好方法?对于这种情况还有另一种最佳做法吗?

回答

0

一种方法是在宝石的类上存根: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 

这似乎很麻烦...有没有更好的方法?

0

老实说,我真的不明白real_cpanel_add_domain在做什么,因为在我看来,它只是分配了两个局部变量,然后在其中一个上调用add_domain,这将如何影响任何东西?我想你可以从params获得域和面板类,默认为CpanelDeployer::DomainCpanelDeployer::Panel,但在规范中传递一些存根。

我不是一个很迷恋new方法的人,因为它并不总是像预期的那样工作。

+0

'real_cpanel_add_domain'是与外界交互的东西。 'cpanel.add_domain()'调用是将网站添加到外部网站中的真实cPanel。有没有更好的方式来做这个外界的互动? 这是有趣的想法注入参数....但我不认为我想要在应用程序中实际使用它... – Josh