mardi 3 février 2015

One Test Case Seems to Interfere the Other Test Case

This is on Rails 4.0.11. I am writing a test using minitest and webmock for a worker that interacts with an API. I have two test cases (so far) in my test file. When I run both tests, the second one (the one with "success" in the title) fails. When I comment out the passing test (the one with "retry" in the title), the test case that was failing passes. It seems like the test cases are interfering with each other, but I don't see how.


(I've obfuscated company confidential data in these code examples. Hi boss!)


Here's the test:



require 'test_helper'

class FoocorpCheckStatusWorkerTest < ActiveSupport::TestCase

REQUEST_HEADERS = {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'text/xml', 'User-Agent'=>'Ruby'}
EXPECTED_BODY = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<POSBizServices xmlns=\"http://api.foocorp.com\">\n <POSBizServiceHeader>\n <userId>ABC</userId>\n <password>abc123</password>\n <clientId>123</clientId>\n <action>CHECKSTATUS</action>\n <responseFormat>XML</responseFormat>\n </POSBizServiceHeader>\n <request>\n <checkStatus>\n <ecpdId>123</ecpdId>\n <refNum>12345678</refNum>\n </checkStatus>\n </request>\n</POSBizServices>\n"

def sample_response_body(order_level_status_code: '', line_level_status_code: '')

return <<-SAMPLE_RESPONSE_BODY
<?xml version="1.0" encoding="UTF-8"?>
<POSBizServices xmlns="http://api.foocorp.com">
<POSBizServiceHeader>
<userId>ABC</userId>
<password>abc123</password>
<clientId>123</clientId>
<statusCode>#{order_level_status_code}</statusCode>
<statusDescription>2015-01-29 14:03:07 [QA13:MS_WSQA4_ONEPOS_01:01] : Request Processed Successfully</statusDescription>
<action>CHECKSTATUS</action>
<responseFormat>XML</responseFormat>
</POSBizServiceHeader>
<response>
<statusResponse>
<count>1</count>
<orderStatus>
<orderId>12345678</orderId>
<orderDate>01/27/2015</orderDate>
<stats>1,0</stats>
<aceOrderNo></aceOrderNo>
<locationCode></locationCode>
<lineInfoList>
<count>1</count>
<lineStatus>
<lineSeq>1</lineSeq>
<statusCode>#{line_level_status_code}</statusCode>
<statusDesc>No Status Yet.</statusDesc>
</lineStatus>
</lineInfoList>
</orderStatus>
</statusResponse>
</response>
</POSBizServices>
SAMPLE_RESPONSE_BODY
end

test "retry codes leave activity processor step in waiting state and activity in auto_processing state" do

activity_processor_step = activity_processor_steps(:vip_vm_password_reset_step)
activity = activity_processor_step.activity

FoocorpVipCheckStatusWorker::STATUS_CODE_MATRIX[:retry].each do |status_code_pair|

stub_request(:post, FOOCORP_VIP_CONFIG[:base_url]).
with(:body => /^.*$/,
:headers => REQUEST_HEADERS
).
to_return(:status => 200, :body => sample_response_body(order_level_status_code: status_code_pair.first, line_level_status_code: status_code_pair.last), :headers => {})

FoocorpVipCheckStatusWorker.new.perform

activity.reload
assert_equal("auto_processing", activity.state)

activity_processor_step.reload
assert_equal("waiting", activity_processor_step.state)

end
end

test "success codes complete activity and activity processor step" do

activity_processor_step = activity_processor_steps(:vip_vm_password_reset_step)
activity = activity_processor_step.activity

FoocorpVipCheckStatusWorker::STATUS_CODE_MATRIX[:success].each do |status_code_pair|

stub_request(:post, FOOCORP_VIP_CONFIG[:base_url]).
with(:body => /^.*$/,
:headers => REQUEST_HEADERS
).
to_return(:status => 200, :body => sample_response_body(order_level_status_code: status_code_pair.first, line_level_status_code: status_code_pair.last), :headers => {})

FoocorpVipCheckStatusWorker.new.perform

activity.reload
assert_equal("completed", activity.state)

activity_processor_step.reload
assert_equal("completed", activity_processor_step.state)
end
end
end


Here's the worker:



class FoocorpVipCheckStatusWorker
@queue = :short_running

# Foocorp VIP returns an order-level status code and description
# and a line-level status code and description. The comments describing
# the status codes in STATUS_CODE_MATRIX are from Foocorp's Docs.
#
# Array format for status codes is:
# ["(order-level status code)", "(line-level status code)"]

STATUS_CODE_MATRIX = {
:success => [
["00057", "00051"] # Request Processed Successfully
],
:retry => [
["00057", "00053"], # No Status Yet
["00057", "00054"], # Order processed successfully but activation is pending.
["00099", ""], # Unexpected error occurred during processing e.g. null pointer exception which causes thread to terminate.
["00059", ""], # Server time out occurred.
["10009", ""], # Back End call returned invalid agent data.
["10010", ""], # Application fails to load ECPD profile details.
["00058", "10013"], # Backend calls fails to load Billing information for account. It may be due to some internal issue.
["00058", "10032"], # Exception occurred in Bulk Service write
["00058", "10033"], # Error occurred in Bulk Service write for reassign
["00058", "10040"], # Sub Account create failed
["00058", "10144"] # UNABLE TO RETRIEVE CREDIT INFORMATION
]
}

def perform

ActivityProcessorStep.where(state: "waiting").where("vip_ref_num IS NOT NULL").each do |activity_processor_step|

client = Remote::Clients::FoocorpVipClient.new(
:params => {
:ecpd_id => activity_processor_step.activity.carrier_account.parent_account.api_access_id,
:vip_ref_num => activity_processor_step.vip_ref_num
}
)
response = client.check_status
#TODO: Remove debugging code
#binding.pry
order_status_code = response.first[:order_status_code]
order_status_desc = response.first[:order_status_desc]
line_status_code = response.last[:line_status_code]
line_status_desc = response.last[:line_status_desc]

status_codes = [order_status_code, line_status_code]
response_message = line_status_desc.present? ? line_status_desc : order_status_desc
response_message ||= "No status description given"

success = STATUS_CODE_MATRIX[:success].detect{ |codes_array| codes_array == [order_status_code, line_status_code]}.present?
retry_status_check = STATUS_CODE_MATRIX[:retry].detect{ |codes_array| codes_array == [order_status_code, line_status_code]}.present?
stale_request = retry_status_check && Time.now > (activity_processor_step.created_at + activity_processor_step.days_to_expire.days)

if success
activity_processor_step.update_activity_status('Complete', nil, nil, response_message)
elsif stale_request
activity_processor_step.update_activity_status('Failure', nil, nil, "Activity processor step expired.")
elsif !retry_status_check
activity_processor_step.update_activity_status('Failure', nil, nil, response_message)
end

end
end
end


Here's my terminal output:


Running both test cases:



me@domo-kun ~/my-project (feature_foocorp_check_status_worker=)$ be rake test TEST=test/workers/foocorp_check_status_worker_test.rb
Run options: --seed 58882

# Running tests:

.F

Fabulous tests in 2.009658s, 0.9952 tests/s, 11.4447 assertions/s.

1) Failure:
FoocorpCheckStatusWorkerTest#test_success_codes_complete_activity_and_activity_processor_step [/Users/steven/Development/my-company/my_company/test/workers/foocorp_check_status_worker_test.rb:86]:
Expected: "completed"
Actual: "auto_processing"

2 tests, 23 assertions, 1 failures, 0 errors, 0 skips


Commenting out the first ("retry") test case:



me@domo-kun ~/my-project (feature_foocorp_check_status_worker=)$ be rake test TEST=test/workers/foocorp_check_status_worker_test.rb
Run options: --seed 14937

# Running tests:

.

Fabulous tests in 3.474386s, 0.2878 tests/s, 0.5756 assertions/s.

1 tests, 2 assertions, 0 failures, 0 errors, 0 skips


When I run both tests together and use binding.pry (commented out here) in the worker to examine the value of response during the "success" test case (the one that fails), I get the following two results. I expect the same result (the second one) in both cases.


Running both test cases:



[1] pry(#<VerizonVipCheckStatusWorker>)> response
=> [{:order_status_code=>"00057",
:order_status_desc=>"",
:_summary=>{:order_status_code=>"00057", :order_status_desc=>""}},
{:line_status_code=>"00053",
:line_status_desc=>"No Status Yet.",
:_summary=>{}}]


Commenting out the first ("retry") test case:



[2] pry(#<VerizonVipCheckStatusWorker>)> response
=> [{:order_status_code=>"00057",
:order_status_desc=>"",
:_summary=>{:order_status_code=>"00057", :order_status_desc=>""}},
{:line_status_code=>"00051",
:line_status_desc=>"No Status Yet.",
:_summary=>{}}]


The value of response in that last example is what I would expect it to be during the first iteration of the "retry" test case, not during the "success" case.


I've tried moving what was in a setup method into the constants and sample_response_body method you see here. I also tried adding this teardown method, but it didn't help:



def teardown
WebMock.reset!
end


I'm writing both the worker and the test from scratch, so it's entirely possible that I have a dumb syntax/logic errors somewhere. I apologize for what is probably an overly verbose question, but this really has me tearing my hair out. Your help is appreciated. Thanks.


Aucun commentaire:

Enregistrer un commentaire