Open janhh opened 10 years ago
Interesting issue @janhh -- could you expand more on "Savon mocks the service I am testing against"? If I understand correctly, it sounds like you're using this in a test environment and you're mocking the actual HTTP response?
If possible. could you share a small snippet of code that illustrates this problem? It's my understanding that this would occur when the WSDL does not have any message
nodes, but I can't imagine a WSDL without at least one <message>
element.
I use mocking feature to test my implementation, hopefully my code snippets below illustrate what I mean.
Client:
require 'savon'
module WsEsaOffentlig
module V8041_10512
class OffentligServiceClient
CDATA_FORMAT = '<![CDATA[%s]]>'
def initialize(endpoint = 'http://localhost')
@client = Savon.client(wsdl: wsdl_file_path, endpoint: endpoint)
end
def search_off_journal(where, order_by, max_no_of_hits)
message = {
where: CDATA_FORMAT % where,
order_by: order_by,
max_no_of_hits: max_no_of_hits
}
@client.call(:search_off_journal, message: message)
end
def wsdl_file_path
File.expand_path("../../wsdl/offentlig-service/offentlig_1.wsdl", __FILE__)
end
end
end
end
Spec:
require 'savon/mock/spec_helper'
require_relative '../../../../../../../lib/impl/ws_esa_offentlig/v8041_10512/clients/offentlig_service_client.rb'
module WsEsaOffentlig
module V8041_10512
describe 'OffentligServiceClient' do
include Savon::SpecHelper
before(:all) {savon.mock!}
after(:all) {savon.unmock!}
describe "#wsdl_file_path" do
it "returns a file path that is available" do
file_path = VersionClient.new.wsdl_file_path
expect(File.exist?(file_path)).to be true
end
end
describe "#search_off_journal" do
it "should return many ids when where clause is within september 2014" do
fixture = File.read(File.expand_path("../../fixtures/offentlig_service_search_off_journal_september_response.xml", __FILE__))
where = "jpjdato >= '08.09.14' AND jpjdato < '11.09.14'"
order_by = ''
max_no_of_hits = ''
message = {
where: "jpjdato >= '08.09.14' AND jpjdato < '11.09.14'",
order_by: order_by,
max_no_of_hits: max_no_of_hits
}
expected_message = message
# Wrap message with CDATA.
expected_message[:where] = OffentligServiceClient::CDATA_FORMAT % message[:where]
savon.expects(:search_off_journal).with(message: expected_message).returns(fixture)
client = OffentligServiceClient.new
response = client.search_off_journal(where, order_by, max_no_of_hits)
expect(response).to be_successful
end
end
end
end
end
The WSDL is spread out in different files, and uses wsdl:import statements. I used SoapUI to export definitions from actual Web Service.
I ran into this issue as well. What version of Nokogiri are you running? That turned out to be my problem. Wasabi only requires Nokogiri 1.4.0, but element_children were not put in until 1.4.2. If you update Nokogiri, it will probably fix this issue.
Hi, thanks for the suggestion. Actually, savon 2.6.0 depends on nokogiri 1.6.3.1.
I got around this issue by using JRuby and Java Axis2 client instead. But I still have a branch of the MRI attempt in our Git tree.
The problem occurs when an HTML doc is returned by a server and passed to Nokogiri.XML
. In this case the document's root in nil
:
irb [2.1.3] (sshaw-savon)$ Nokogiri::XML("<!doctype html><head></head><body></body>").root
=> nil
You can reproduce this using Savon with:
client = Savon.client(wsdl: "http://example.com")
client.call(:xxxx, message: "Death to Saxon XSLT!")
The result:
/Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/parser.rb:311:in `sections': undefined method `element_children' for nil:NilClass (NoMethodError)
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/parser.rb:304:in `section'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/parser.rb:294:in `schemas'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/parser.rb:67:in `parse_namespaces'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/parser.rb:54:in `parse'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/document.rb:161:in `parse'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/document.rb:147:in `parser'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/wasabi-3.3.0/lib/wasabi/document.rb:64:in `soap_actions'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/savon-2.8.1/lib/savon/operation.rb:21:in `ensure_exists!'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/savon-2.8.1/lib/savon/operation.rb:14:in `create'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/savon-2.8.1/lib/savon/client.rb:32:in `operation'
from /Users/sshaw/.rvm/gems/ruby-2.1.3/gems/savon-2.8.1/lib/savon/client.rb:36:in `call'
Hah, great catch @sshaw! I think the fix for this would be to catch this and return an error in this case, rather than trying to parse an HTML body. Will see if I can find time to fix this sometime next week, but if someone wants to issue a PR for this I'd be more than happy to help out.
Hi, I receive a "undefined method" message at parser.rb:318. See attached screenshot, and the code in link. https://github.com/savonrb/wasabi/blob/v3.3.1/lib/wasabi/parser.rb#L318
The \@messages object is an empty hash and the port_message_type variable has a variable. Savon mocks the service I am testing against.
If I add a "if message" at the end of line 320, my rspec fails at parser.rb:260 with same error message. Interestingly, adding if check made test pass when I used wasabi 3.3.0 IIRC.