Error with Web Service tests after upgrading to Rails 1.1.2


#1

Hello.

I hope this is the right place to describe my problem â?¦

After upgrading to Rails version 1.1.2 from rails version 1.0.0, Web
Service functional tests seem broken.

I upgraded rails (as the root user / administrator) with:

gem update rails --include-dependencies

then I upgraded my application (as myself) with:

½ rake rails:update
% rake rails:update:configs

After these steps, working before Web Services functional tests broke.

To try to isolate the problem, I scaffolded a simple Web Services
Controller:

% ./script/generate web_service Problem my_method

Running the test on this Controller, I get:

% ruby test/functional/problem_api_test.rb
Loaded suite test/functional/problem_api_test
Started
E
Finished in 0.047129 seconds.

  1. Error:
    test_my_method(ProblemControllerApiTest):
    NoMethodError: You have a nil object when you didn’t expect it!
    You might have expected an instance of Array.
    The error occured while evaluating nil.length
    /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:55:in
    encode_rpc_call' /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:36:inprepare_request’
    /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:9:in
    invoke' test/functional/problem_api_test.rb:14:intest_my_method’

1 tests, 0 assertions, 0 failures, 1 errors

The freshly scaffolded files are:

* app/apis/problem_api.rb

  class ProblemApi < ActionWebService::API::Base
    api_method :my_method
  end

* app/controllers/problem_controller.rb

  class ProblemController < ApplicationController
    wsdl_service_name 'Problem'

    def my_method
    end
  end

* test/functional/problem_api_test.rb

  require File.dirname(__FILE__) + '/../test_helper'
  require 'problem_controller'

  class ProblemController; def rescue_action(e) raise e end; end

  class ProblemControllerApiTest < Test::Unit::TestCase
    def setup
      @controller = ProblemController.new
      @request    = ActionController::TestRequest.new
      @response   = ActionController::TestResponse.new
    end

    def test_my_method
      result = invoke :my_method
      assert_equal nil, result
    end
  end

On my real application, Web Services working before tests return many
more errors, like:

% ruby test/functional/web_svc/backend_api_test.rb
Loaded suite test/functional/web_svc/backend_api_test
Started
E…FF…E
Finished in 0.557281 seconds.

  1. Error:
    test_find_all_softwares(WebSvc::BackendControllerApiTest):
    NoMethodError: You have a nil object when you didn’t expect it!
    You might have expected an instance of Array.
    The error occured while evaluating nil.length
    /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:55:in
    encode_rpc_call' /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:36:inprepare_request’
    /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:9:in
    invoke' test/functional/web_svc/backend_api_test.rb:90:intest_find_all_softwares’

  2. Failure:
    test_new_bad_category(WebSvc::BackendControllerApiTest)
    [test/functional/web_svc/backend_api_test.rb:33]:
    exception expected but none was thrown.

I am using Ruby version ruby 1.8.4 (2005-12-24) [i386-linux].

So where is the problem? What am I doing wrong?

Thank you very much for your help!


#2

In your example you haven’t specified that ProblemController implements
ProblemApi. But I agree that AWS should report this error in more
friendly
manner.


#3

http://dev.rubyonrails.org/ticket/4720


#4

Thank you, Kent.

Kent S. wrote:

In your example you haven’t specified that ProblemController implements
ProblemApi. But I agree that AWS should report this error in more
friendly
manner.

Should I?

According to the “Agile Web D. with Rails” book, since the
Controller name corresponds to the API, that is not required. And it
worked in Rails 1.0. Finally, I scaffolded the API, the Controller
and the Test file, without changing anything myself. And I thought
this must work out of the box …

Of course, I tried you suggestion. But the error persists:

% cat app/controllers/problem_controller.rb
class ProblemController < ApplicationController
  wsdl_service_name 'Problem'

  web_service_api ProblemApi

  def my_method
  end
end

% ruby test/functional/problem_api_test.rb

Loaded suite test/functional/problem_api_test
Started
E
Finished in 0.05925 seconds.

1) Error:

test_my_method(ProblemControllerApiTest):
NoMethodError: You have a nil object when you didn’t expect it!
You might have expected an instance of Array.
The error occured while evaluating nil.length
/usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:55:in
encode_rpc_call' /usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:36:inprepare_request’
/usr/lib/ruby/gems/1.8/gems/actionwebservice-1.1.2/lib/action_web_service/test_invoke.rb:9:in
invoke' test/functional/problem_api_test.rb:14:intest_my_method’

1 tests, 0 assertions, 0 failures, 1 errors

Finally, I generated a completely new Rails test application,
with just an AWS scaffolded controller with one method, without
changing anything to the files, and the error is still there…

Or maybe my implementation declaration is bad?

Thank you again.

Best regards !


#5

Give an example please.


#6

Kent S. wrote:

http://dev.rubyonrails.org/ticket/4720

Great, thank you very much, Kent !!!

This solved my scaffolded only test case error. And in
my real test case code, I had two api methods without
‘:expects’ clause. Adding ‘:expects => []’ corrected those
errors.

What remains are two failures. In my test I checked for
bed arguments passes, violating a validation model parameters.
In Rails 1.0 the ‘RuntimeError’ was returned by the AWS call.
It seems that errors are no more returned. Is this right? And
how can I find on tha calling side that something went wrong?


#7

Does your ‘new_category’ method throw RuntimeError?

I don’t see why ActiveRecord should throw RuntimeError. If your
Category instance is invalid Category#save returns false and
Category#save! throws ActiveRecord::RecordInvalid exception.

Kent.

On 4/14/06, Krassimir T. removed_email_address@domain.invalid wrote:

end
def test_new_bad_category
But the new object is not inserted, because of the duplicate name:
invoke :new_category, new_cat_args[:name],


Posted via http://www.ruby-forum.com/.


Rails mailing list
removed_email_address@domain.invalid
http://lists.rubyonrails.org/mailman/listinfo/rails


Kent

http://www.datanoise.com


#8

You must be right … there is nothing telling that such an Error should
be risen. I am new in Ruby and in Rails, and I thought that a failing
validation should announce this. And from my previous functional tests,
that’s the behaviour I constated, But I’me certainly wrong.

Thank you for this explanation.

Kent S. wrote:

Does your ‘new_category’ method throw RuntimeError?

I don’t see why ActiveRecord should throw RuntimeError. If your
Category instance is invalid Category#save returns false and
Category#save! throws ActiveRecord::RecordInvalid exception.

Kent.


#9

Kent S. wrote:

Give an example please.

In my tests I am trying to remotely insert a new category object
with a name already existing, so this is not allowed:

class Category < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => “parent_id”
# …
end

In Rails 1.0 this worked, because a ‘RuntimeError’ was received by the
caller, and by the test case:

def setup
  # ...
  @top_os_linux_category = categories(:top_os_linux)
end

def test_new_bad_category
  cat_count = Category.count
  new_cat_args = { :name => @top_os_linux_category.name,
    :parent_id => @top_os_linux_category.parent_id }
  assert_raise(RuntimeError) { invoke :new_category,
    new_cat_args[:name], new_cat_args[:parent_id] }
  assert_equal cat_count, Category.count
end

After upgrading to Rais 1.1.2, this is the test code that works.
I see, that the ‘RuntimeError’ is no more got by the AWS caller.
But the new object is not inserted, because of the duplicate name:

def setup
  # ...
  @top_os_linux_category = categories(:top_os_linux)
end

def test_new_bad_category
  cat_count = Category.count
  new_cat_args = { :name => @top_os_linux_category.name,
    :parent_id => @top_os_linux_category.parent_id }
  invoke :new_category, new_cat_args[:name], 

new_cat_args[:parent_id]
assert_equal cat_count, Category.count
end

How the calling program could find that the object insertion vanished,
without asking agin for the number of ‘Category’ object instances?
Before
the ‘RuntimeError’ was a such indication.

Thank you very much!