Насмешка над динамически генерируемым классом в метапрограммировании ruby ​​с помощью rspec - PullRequest
1 голос
/ 29 ноября 2011

Я новичок в метапрограммировании TDD и , так что терпите меня!

У меня есть класс Reporter (для переноса рубинового драгоценного камня Garb), который будет генерировать новый класс отчета пои назначьте его модулю GoogleAnalyticsReport, когда я нажму method_missing.Основная суть заключается в следующем:

Reporter.rb

def initialize(profile)
        @profile = profile
    end

def method_missing(method, *args)

        method_name = method.to_s
        super unless valid_method_name?(method_name)

        class_name = build_class_name(method_name)
        klass = existing_report_class(class_name) || build_new_report_class(method_name, class_name)
        klass.results(@profile)
    end

def build_new_report_class(method_name, class_name)
        klass = GoogleAnalyticsReports.const_set(class_name, Class.new)
        klass.extend Garb::Model
        klass.metrics << metrics(method_name)
        klass.dimensions << dimensions(method_name)
        return klass
    end

Тип «профиля», который, как ожидает Reporter, представляет собой Garb :: Management :: Profile.

Чтобы протестировать некоторые из моих личных методов в этом классе Reporter (например, valid_method_name? Или build_class_name), я считаю, что хочу смоделировать профиль с помощью rspec, поскольку это не деталь, которая меня интересует.

Тем не менее, вызов klass. results (@ profile) - выполняет и убивает меня, поэтому я не заглушил Garb :: Model, которую я расширяю в своей мета части.

Вот как я до сих пор издеваюсь и заглушаюсь ... реализация спецификации, конечно, не важна:

describe GoogleAnalyticsReports::Reporter do
before do

@mock_model = mock('Garb::Model')
@mock_model.stub(:results) # doesn't work!

@mock_profile = mock('Garb::Management::Profile')
@mock_profile.stub!(:session)

@reporter = GoogleAnalyticsReports::Reporter.new(@mock_profile)

end

describe 'valid_method_name' do
it 'should not allow bla' do
    @reporter.valid_method_name?('bla').should be_false
end


end
end

Кто-нибудь знает, как я могу заглушить вызов * 1021?* результаты метод для моего недавно созданного класса?

Любые указатели будут с благодарностью!

~ Stu

1 Ответ

2 голосов
/ 29 ноября 2011

Вместо:

@mock_model = mock('Garb::Model')
@mock_model.stub(:results) # doesn't work!

Я думаю, что вы хотите сделать:

Garb::Model.any_instance.stub(:results)

Это заглушит любой экземпляр Garb :: Model для возврата результатов.Вы должны сделать это, потому что вы на самом деле не передаете @mock_model ни в один класс / метод, который будет его использовать, поэтому вам нужно быть немного более общим.

...