Squeak - SUnit Testing for Errors - squeak

I have been suggested to use should:rise in my test case to test for errors that a method might raise. For some reason it does not work as expected, so I want to verify that I'm doing it right. Here is the code in the test case:
self should: [aMyClass compareTo: 'This is a string'] raise: 'invalid input'.
My compareTo/1 method looks like this:
(aMyClass isKindOf: MyClass) ifFalse: [self error: 'invalid input'.].
The test runner output is that there is "1 errors".
Thank you.

#should:raise: expects an Exception class as its second argument, similar to the first argument of #on:do: in exception handling:
self should: [ aMyClass compareTo: 'This is a string' ] raise: Error

Related

Trouble mocking `Resolv::DNS.open`

I'm trying to mock the code below using MiniTest/Mocks. But I keep getting this error when running my test.
Minitest::Assertion: unexpected invocation: #<Mock:0x7fa76b53d5d0>.size()
unsatisfied expectations:
- expected exactly once, not yet invoked: #<Mock:0x7fa76b53d5d0>.getresources("_F5DC2A7B3840CF8DD20E021B6C4E5FE0.corwin.co", Resolv::DNS::Resource::IN::CNAME)
satisfied expectations:
- expected exactly once, invoked once: Resolv::DNS.open(any_parameters)
code being tested
txt = Resolv::DNS.open do |dns|
records = dns.getresources(options[:cname_origin], Resolv::DNS::Resource::IN::CNAME)
end
binding.pry
return (txt.size > 0) ? (options[:cname_destination].downcase == txt.last.name.to_s.downcase) : false
my test
::Resolv::DNS.expects(:open).returns(dns = mock)
dns.expects(:getresources)
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.returns([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
.once
Right now you are testing that Resolv::DNS receives open returns your mock but
since you seem to be trying to test that the dns mock is receiving messages you need to stub the method and provide it with the object to be yielded
Try this instead:
dns = mock
dns.expects(:getresources)
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.once
::Resolv::DNS.stub :open, [Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)], dns do
# whatever code actually calls the "code being tested"
end
dns.verify
The second argument to stub is the stubbed return value and third argument to stub is what will be yielded to the block in place of the original yielded.
In RSpec the syntax is a bit simpler (and more semantic) such that:
dns = double
allow(::Resolv::DNS).to receive(:open).and_yield(dns)
expect(:dns).to receive(:getresources).once
.with(subject.cname_origin(true), Resolv::DNS::Resource::IN::CNAME)
.and_return([Resolv::DNS::Resource::IN::CNAME.new(subject.cname_destination)])
# whatever code actually calls the "code being tested"
You can write more readable integration tests with DnsMock instead of stubbing/mocking parts of your code: https://github.com/mocktools/ruby-dns-mock

Is it possible to change the output of Lua error messages?

I managed to change the output of error messages by modifying the dbg_printf method. However, that method doesn't handle the following error messages:
lua: ?:0: attempt to call global 'log' (a nil value)
Which method(s) handle these types of errors?
The error message is from the file ldebug.c in the function luaG_typeerror. But i guess you are using an older Lua Version because my message is a bit different:
attempt to call a nil value (global 'log')
You sould try to prevent the error if you can:
if type(log) == "function" then
log()
end
or as #lhf said use pcall:
if pcall(log) then
-- no errors while running 'log'
...
else
-- 'log' raised an error: take appropriate actions
...
end
It should be simpler than digging into the C api.
like #lhf says:
if pcal(risky) then
print("this works")
else
print("phooey!")
end
alternatively you can stop the program and get your error message like this:
if pcal(risky) then
print("this works")
else
error("your error message here")
end

WithNewWindow() returns MultipleCompilationErrorsException in Geb

I am getting weird error in my geb functional tests.
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Spec expression: 1: expecting '}', found 'assert' # line 1, column 71.
} ) { at(JobOfferDetailPage) assert des
My test looks like this. I click on a link which opens a new window with details of the job offer. Than I want to assert some text on the new page using Page Pattern.
Test:
withNewWindow( { quickShowOption.click() } ) { //TODO fix me
at(JobOfferDetailPage)
assert description.text() == 'some text'
assert requirements.text() == 'some text'
assert advatages.text() == 'some text.'
assert categories.text() == 'some text'
assert locality.text() == 'some text'
}
Page:
class JobOfferDetailPage extends Page {
static at = {$('#contactLabel').text() == 'Contact'}
static content = {
description {$('#jobOfferDescription')}
requirements {$('#jobOfferRequirements')}
advatages {$('#jobOfferAdvantages')}
jobOfferType {$('#jobOfferType')}
categories {$('#categories')}
locality {$('#locality')}
startDate {$('#startDate')}
requiredLanguages {$('#requiredLanguages')}
}
}
I get compilation error after my conditions are asserted. If I make a typo in asserted text than the test will fail normally, but if it passes, than it fails with this weird error.
Thank you #Erdi.
I use spock,geb versions "0.13.1" and selenium version "2.51.0".
If one was to believe this comment in one of Geb's own tests, which was nota bene written by me some time ago, this indeed seems like some sort of bug in Spock. What is interesting is that I just now moved that statement to an expect block and it works as long as the last statement in the second closure passed to newWindow() evaluates to true. This makes me think that it is an issue with old version of Spock and/or Groovy. Which versions of the aforementioned tools are you using?
One possible workaround would be to move your statement from expect/then to one that is not asserting (given or when) as shown in the test I linked to.

How to unit test a method for timeout exception in ruby

I want to test a method which makes a call to a service, if the call to that service times out I am displaying a negative feedback to user. How to unittest the timeout use case ??
My method looks like:
def method
x = callservice()
if x[:value]
display_positve_feedback("positive")
else
display_negative_feedback("negative")
end
rescue Timeout::Error => e
display_negative_feedback("Timeout, please wait for 5 mins and check again")
end
end
I have mocked callservice but how to I make that service Timeout to check the timeout use case???
You don't use a return code. If you add it, you could test for the method result.
Example:
def method
begin
x = callservice()
if x[:value]
display_positve_feedback("positive")
return true
else
display_negative_feedback("negative")
return false
end
rescue Timeout::Error => e
display_negative_feedback("Timeout, please wait for 5 mins and check again")
return nil
end
raise "This should never happen"
end
Now you can test on true, falseor nil.
Suppressing exceptions is usually not a good practice that I would recommend to anyone.
When you catch (rescue) the timeout exception, re-raise it (or your own application-specific one) in the rescue code and have the caller (your test) check that an exception is thrown for the timeout.
You could use assert_raise or expect raise_error, for example, depending on what testing framework you use.
Using an exception, the calling code only needs to know about a potential exception rather than having to check for specific return values, which makes the code simpler and more clear.
Stub the callservice method to raise a Timeout::Error. How you'll do that depends on what testing framework you're using. For example, in RSpec it might look something like this:
my_obj.stub(:callservice) { raise Timeout::Error }
expect(my_obj).to receive(:display_negative_feedback)
.with("Timeout, please wait for 5 mins and check again")
my_obj.method

error message test on minitest

I use mini_test for testing. I have a code part like below.
raise Type_Error, 'First Name must not be empty' if #person.first_name == nil
How can I write this code's test?
Thanks...
I think you want assert_raises, which asserts that the block/expression passed to it will raise an exception when run.
For example, one of my projects has the following minitest:
test 'attempting to create a CreditCard that fails to save to the payment processorshould prevent the record from being saved' do
assert_equal false, #cc.errors.any?
failure = "simulated payment processor failure"
failure.stubs(:success?).returns(false)
failure.stubs(:credit_card).returns(nil)
PaymentProcessor::CreditCard.stubs(:create).returns(failure)
assert_raises(ActiveRecord::RecordNotSaved) { create(:credit_card) }
end
What this does, in my case, is:
Create a simulated failure message from the payment processor API
Stub the creation of a credit card on the payment processor to return the simulated failure
Try to create a credit card, simulating that the payment processor has returned a failed status, and assert that my internal save/create method throws an error under these conditions
I should say that this test code includes things in addition to minitest, such as FactoryGirl, and (I think) shoulda and mocha matchers. In other words, what is shown above isn't strictly minitest code.
raise Type_Error, 'First Name must not be empty' if #person.first_name == nil
For testing above line, I wrote a test like below. I used minitest::spec for this.
def test_first_name_wont_be_nil
person.name = nil
exception = proc{ Context.new(person).call }.must_raise(TypeError)
exception.message.must_equal 'First Name must not be empty'
end
Context is place where make some process.

Resources