2015-12-15 31 views
5

Chcę zastąpić metodę Selenium::WebDriver.for. To, co starałem:Jak zastąpić metody klasy

module SeleniumWebDriverExtension 
    def self.for(browser, *args) 
    if browser != :phantomjs 
     super(browser, *args) 
    else 
     options = { 
      "phantomjs.cli.args" => ["--ssl-protocol=tlsv1"] 
     } 
     capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs(options) 
     super(browser, desired_capabilities: capabilities) 
    end 
    end 
end 

Selenium::WebDriver.prepend(SeleniumWebDriverExtension) 

Ale mam błąd podczas Selenium::Webdriver.for(:phantomjs) nazywa.

NoMethodError: super: no superclass method `for' for Selenium::WebDriver::Driver:Class 

Jak mogę wywołać oryginalną metodę z metody przesłaniania?

Odpowiedz

9
module SeleniumWebDriverExtension 
    def for(browser, *args) 
    ... 
    end 
end 

Selenium::WebDriver.singleton_class.prepend(SeleniumWebDriverExtension) 
+1

Sprytnie, dzięki! Teraz używamy tego, aby zmienić 'NewRelic :: Agent :: Hostname.get' z powrotem do super. – Raffael

4

Kiedy używasz self wewnątrz modułu tak:

def self.for(browser, *args) 

end 

jest zadeklarowana jako module function, a nie metodę instancji na klasy, która będzie zawierać ten moduł. Oznacza to, że nie pojawią się one na dołączonych klasach, gdy moduł zostanie pomieszany z inną klasą.

Jest ona podobna do pisania:

def SeleniumWebDriverExtension::for 
end 

Więc jeśli chcesz zadzwonić super od wewnątrz modułu, zadeklarować go jako prosty instance method jakby przyjął odpowiedź zasugerował. Chciałem tylko wyjaśnić ci powód tego.

Btw SeleniumWebDriverExtension.ancestors dla jasności w hierarchii dziedziczenia.