I have to test the class Lextm.SharpSnmpLib.Pipeline.ISnmpContext with the following methods
get_Binding
get_CreatedTime
get_Request
get_Response
get_Sender
but not a unit test, i need a test case and i should not modify the library itself but only using it. I thought about using the snmptrapd already in the code examples but i have no idea how to call in particular those methods above without modifying the library and i cannot find any example.I see there is something in the Rolling Logger in the GetLogEntry method but as said i need help to get an Isnmp context first
Thanks
Related
I am testing a class that makes use of a client that makes external requests and I would like to mock this client, but verify that it gets called, however I am getting a double error.
My test looks like something like this:
describe '#execute' do
let(:attributes) { {foo: 'bar'} }
let(:client_double) { double('client', create: nil) }
let(:use_case) { described.class.new }
before do
allow(Client::Base).to receive(:new).and_return(client_double)
use_case.execute(attributes)
end
it 'creates something' do
expect(Something.find_by(foo: 'bar')).not_to be_nil
end
it 'calls client' do
expect(client).to have_received(:create).with('bar')
end
end
and the first example passes as expected, however rspec keeps breaking in the second example giving me this error:
#<Double "foo"> was originally created in one example but has leaked into another example and can no longer be used. rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.
someone knows what I can do to fix it?
Reusing Fixtures with Let Methods
In this case, before is actually before(:each), which is reusing the client_double and attributes you defined with the #let helper method. The let commands make those variables functionally equivalent to instance variables within the scope of the described object, so you aren't really testing freshly-created objects in each example.
Some alternatives include:
Refactor to place all your setup into before(:each) without the let statements.
Make your tests DAMP by doing more setup within each example.
Set up new scope for a new #describe, so your test doubles/values aren't being reused.
Use your :before, :after, or :around blocks to reset state between tests, if needed.
Since you don't show the actual class or real code under test, it's hard to offer specific insights into the right way to test the object you're trying to test. It's not even clear why you feel you need to test the collaborator object within a unit test, so you might want to give some thought to that as well.
It turns out I was using a singleton as a client and haven't realized before, so it was trully class caching it through examples. To fix it all I did was mock the instantiate method instead of the new method and everything worked.
So in the end this worked:
allow(Client::Base).to receive(:instantiate).and_return(client_double)
I've been working to diagnose a test failure that only occurs on my master branch. Following is the relevant code, in simplified form.
There's a service:
class Service
attr_reader :traces
def initialize
#traces = []
end
def do_work
#traces << Thread.current.backtrace
# ... actual work ...
end
end
And a class that makes use of the service:
class Widget
def get_cached_service
puts("Getting a cached service!")
puts("Do I already have one? #{!!#service}")
#service ||= make_service
end
def make_service
puts("Making a service!")
Service.new
end
end
I have a test (that lives in a file widget_spec.rb) that fails intermittently. This test creates an instance of Widget and calls get_cached_service. I see the Getting a cached service! message on the console, followed by Do I already have one? false, but I don't see the Making a service! message.
Furthermore, when I examine the traces attribute of the returned Service object, I find stack traces originating from other tests in my project (eg. foo_spec.rb, bar_spec.rb, etc).
In a few different places I find code like:
allow_any_instance_of(Widget)
.to receive(:make_service).and_return(whatever)
The other tests whose stack traces I find are likely stubbing make_service like this. But it appears that the stubbing is not being undone after those tests, as should always happen according to my understanding.
Is there any reason, other than a bug in rspec, that could cause a stub not to be reset at the end of a test?
The stub is almost certainly being cleared, but you’ve cached the fake instance in get_cached_service. Nothing clears the cached value in #service, and RSpec (rightfully) doesn’t know about it. As such, stubbing make_service is not enough if tests call get_cached_service. You have a few options:
Always stub get_cached_service instead of, or in addition to, make_service
Provide a way to clear the cached value which is called after each test.
Make the caching configurable in some way, or a wrapper around the actual implementation, such that the caching does not occur in test code.
I realise this is quite late to answer, but for posterity for anyone who reads this:
Use rspec bisect to figure out if there is a consistent test ordering that causes failure, then start ripping code out until you're left with only the bit that breaks.
I can't remember a case where RSpec is at fault - almost invariably, somewhere there is a class variable that isn't getting cleared, or someone is manually playing with a class with something like define_method. Occasionally it might be happening in a gem.
Make sure everything is cleared after every test in your spec_helper - clear the Rails cache, clear ActionMailer deliveries, return from Timecop freezes, etc.
Anything directly RSpec-related should clear itself in theory, because it's designed to integrate into RSpec, and is probably the least likely explanation in general.
I've stumbled upon the following piece of code in an Rspec test and I must say I more or less figured out what it does but I can't find relevant sources to prove it. Please point me to a gem or docs that describe:
describe SomeModule::Salesforce::Lead do
before do
SomeModule::Salesforce::Lead.any_instance.expects(:materialize)
end
...
end
It seems that for :each example in this spec it sets expectation on any instance of the class described above to receive a call to :materialize method AND it actually redefines the method to do nothing . The last part seems crucial because it avoids connecting to SalesForce in test environment but I can't find confirmation for this.
any_instance is documented under Working with Legacy code
You are correct in that it both sets an expectation and stubs out the original method on any given instance of a class.
Previous versions of RSpec accomplish this by monkeypatch the ruby core classes (Object and BaseObject)
RSpec 3 has a new syntax which does not rely on monkeypatching:
before do
expect_any_instance_of(SomeModule::Salesforce).to receive(:materialize)
end
Ok I've just found that I was looking in wrong sources, it doesn't come from RSpec but from Mocha Mock (expects and any_instance) http://gofreerange.com/mocha/docs/Mocha/Mock.html#expects-instance_method
Thanks #tomasz-pajor #https://stackoverflow.com/users/2928259/tomasz-pajor
I am working through Learn Ruby The Hard Way and came across something intriguing in exercise 49.
In parser.rb I have a function named skip(word_list, word_type) at the top level, which is used to skip through unrequited words (such as stop words) in user input. It is not encapsulated in a class or module. As per the exercise I have to write a unit test for the parser.
This is my code for the Unit Tests:
require "./lib/ex48/parser"
require "minitest/autorun"
class TestGame < Minitest::Test
def test_skip()
word_list = [['stop', 'from'], ['stop', 'the'], ['noun', 'west']]
assert_equal(skip(word_list, 'stop'), nil)
assert_equal(skip([['noun', 'bear'], ['verb', 'eat'], ['noun', 'honey']], 'noun'), nil)
end
end
However, when I run rake test TESTOPTS="-v" from the command line, these particular tests are skipped. This seems to be because there is a clash with the skip method in the Minitest module because they run perfectly after I change the name to skip_words.
Can someone please explain what is going on here exactly?
"Top level functions" are actually methods too, in particular they are private instance methods on Object (there's some funkiness around the main object but that's not important here)
However minitest's Test class also has a skip method and since the individual tests are instance methods on a subclass of Test you end up calling that skip instead.
There's not a very simple way of dealing with this - unlike some languages there is no easy way of saying that you want to call a particular superclass' implementation of something
Other than renaming your method, you'll have to pick an alternative way of calling it eg:
Object.new.send(:skip, list, type)
Object.instance_method(:skip).bind(self).call(list, type)
Of course you can wrap this in a helper method for your test or even redefine skip for this particular Test subclass (although that might lead to some head scratching the day someone tries to call minitest's skip.
I am new to automation and I have started using Watir Webdriver to automate a website. However, there are certain pieces of code which can be reused for multiple test cases. How can I group the reusable pieces of code into a method which I can call in every test case ? Could you please provide references or examples ?
You are interested in methods.
Here is an example:
def automation_snippet
#browser.text_field(:id => 'field_id').set 'foo'
end
Later you will probably be interested in classes, page objects, and modules.
This is basic ruby stuff. You will need to make sure that whatever method you want to use is in scope, too.
So, keywords to start with are methods and scope. If you are using Cucumber, then you can define methods in any step definition file and they will be available in all your other Cucumber tests.