Mocking a Rails application object with mocha - ruby-on-rails-3

I'm writing a generator and I need to get mock a Rails.application object and get back the Rails.application.class.parent as the name of the Rails application.
def test_model_with_application_namespace
name = "Dummyapp"
application = Rails.stubs(:application).class.parent.returns(name)
run_generator ["file", "--namespaced"]
assert_file "app/models/myapp/file.rb", /class Dummyapp::File < ActiveRecord::Base/
end
This is what I have so far for my test.

You need the object retured by Rails.application.class to be a mock that responds to parent and returns name. Right now, you just stub out application. You need parent, class, and application to be mocks. There is probably a cleaner way of doing it, but I think this will do what you want:
application = Rails.stubs(:application).returns(mock(:class => mock(:parent => name)))

Related

How to Mock private variable in Grails in spock framework

My objective is to Mock the private variable in method of a service class in Grails.
Here I tried bellow way in my test method:
given: 'Mocking of object'
def dataSource = Mock(TransactionAwareDataSourceProxy)
def db1 = Mock(Sql)
service.dataSource = dataSource
new Sql(dataSource) >> db1
List<GroovyRowResult> resultList = new ArrayList<>()
GroovyRowResult result = new GroovyRowResult(id: 0)
result.someAmount = 400
resultList.add(result)
db1.rows(_) >> resultList
In my service class my code is :
def db = new Sql(dataSource)
List<GroovyRowResult> resultList = db.rows("Select * from user_info")
Here, I successfully mocked the TransactionAwareDataSourceProxy named dataSource but I am failed to assign mock def db = new Sql(dataSource) into local private variable db.
I need bellow solution:
How to mock the private variable inside a method. Here, I am assigning Sql in private variable db in my service method
Thanks in advance
The simple answer is: You don't. Instead you refactor to be able to use dependency injection, i.e. pass the Sql instance into the method or into the class. Then you can easily mock it.
See also here and in the other answers linked off of that answer.
The "don't do this at home, kids" part which I do not recommend because it only works for Groovy classes under test and also helps establish bad design in your application code: You can use Spock's Groovy mocks in order to mock constructors. You could achieve the same for Java classes using Mockito, Powermock or my own tool Sarek. Sarek even works for JRE bootstrap classes, also final ones.
But whenever you need Groovy mocks or special add-on tools while writing Spock tests, it is usually a sign you should refactor instead. Only in rare cases where you need to mock something in third party code you are unable to modify, you might need such tools. But even then you can usually refactor your own code in order to access the third party code in such a way that you can inject the right kind of test double (mock, stub, spy) preconfigured to behave like you need it to.

mocking randomnly generated data in rspec

I have a model where it is accepting a set of parameters and tries to do encryption to one parameter and pass the encrypted data to another method.
def post(key, value, data)
business_guid = SecureRandom.uuid
queue_item = "#{key}^#{value}^#{data}"
Queue.create_queue_item(business, Finance, "medium", 2011-12-20, "abc", data)
end
So here I need to mock the data in my rspec and since everytime it creates a random business_guid, my mocked data fails with the newly generated one. So could you please tell me how can I handle it.
(Not sure I understand you correctly)
Why not just to stub it
SecureRandom.stub(uuid: 'some_uuid')
If you are using Minitest (which I highly recommend), you can use a simple Minitest stub:
SecureRandom.stub :uuid, "whateveryouwant" do
SecureRandom.uuid #=> "whateveryouwant"
end
I prefer these because the stub goes away once the block is done! So great.

How to instantiate a BSP controller manually

I tried initially
DATA: cl_rest_bo_list TYPE REF TO zcl_rm_rest_bulk_orders.
CREATE OBJECT cl_rest_bo_list.
cl_rest_bo_list->request->if_http_request~set_method( 'GET' ).
cl_rest_bo_list->do_request( ).
This resulted into an abend, accessing request which was not initialized.
Then I tried to instantiate the request and the response
DATA: cl_rest_bo_list TYPE REF TO zcl_rm_rest_bulk_orders.
DATA: cl_request TYPE REF TO cl_http_request.
DATA: cl_response TYPE REF TO cl_http_response.
CREATE OBJECT cl_rest_bo_list.
CREATE OBJECT cl_request.
CREATE OBJECT cl_response.
request->if_http_request~set_method( 'GET' ).
cl_rest_bo_list->request = cl_request.
cl_rest_bo_list->response = cl_response.
cl_rest_bo_list->do_request( ).
This, at least, does not abend, but the set_method return error code here and does not actually set the method.
system-call ict
did
ihttp_scid_set_request_method
parameters
m_c_msg " > c handle
method " > method
m_last_error. " < return code
Since Google does not know about ihttp_scid_set_request_method, I am pretty sure that I am doing this wrong. Maybe there is no provision to instantiate BSP controllers, though I am not sure what this means for ABAP Unit testing BSP controllers.
As a solution for now I have lifted all business logic into a separate method which gets called/tested without trouble. Still, if anybody knows how to instantiate CL_BSP_CONTROLLER2 classes, that would be great.
As far as I know, the BSP controller can only be instantiated from within the ICF processing because it retrieves information about the call from the kernel. I'm not sure why you would want to install unit tests for the UI in the first place, unless you didn't separate the UI and the business logic as your comment about "lifting" suggests....

Stub method called from constructor when using Fabrication

I've got the following model
class User < ActiveRecord::Base
before_create :set_some_values
private
def set_some_values
#do something
end
end
In specs I'm using Fabrication gem to create objects but I can't find a way to stub the set_some_values method. I tried
User.any_instance.stub!(:set_some_values).and_return(nil)
but Fabrication seems to ignore this. Is it possible to do?
This is why I don't like ActiveRecord callbacks -- because if you want to have nothing to do with a callback (because, say, you're making a call to an external service inside the callback) you still have to be concerned about stubbing it out. Yes you could stub out methods inside the callback, but it's the same problem, and actually it's a bit worse because now you are concerned about something inside a method you want nothing to do with.
As usual there are multiple options here.
One option which I've used a lot in the past is, add a condition to your callback that turns it off by default. So your Post class could look like:
class Post
before_save :sync_with_store, :if => :syncing_with_store?
def syncing_with_store?; #syncing_with_store; end
attr_writer :syncing_with_store
def sync_with_store
# make an HTTP request or something
end
end
Now wherever you really want to call the callback (perhaps in your controller or wherever), you can set post.syncing_with_store = true before you call post.save.
The downside to this approach is, it's something that you (and other devs working with you) have to keep in mind, and it's not really obvious that you have to do this. On the other hand, if you forget to do this, nothing bad happens.
Another option is to use a fake class. Say you have a Post that pushes its data to an external data store on save. You could extract the code that does the pushing to a separate class (e.g. Pusher) which would be accessible at Post.pusher_service. By default, though, this would be set to a fake Pusher class that responds to the same interface but does nothing. So like:
class Post
class << self
attr_accessor :pusher_service
end
self.pusher_service = FakePostPusher
before_save :sync_with_store
def sync_with_store
self.class.pusher_service.run(self)
end
end
class FakePostPusher
def self.run(post)
new(post).run
end
def initialize(post)
#post = post
end
def run
# do nothing
end
end
class PostPusher < FakePostPusher
def run
# actually make the HTTP request or whatever
end
end
In your production environment file, you'd set Post.pusher_service = Pusher. In individual tests or test cases, you'd make a subclass of Post -- let(:klass) { Class.new(Post) } -- and set klass.pusher_service = Pusher (that way you don't permanently set it and affect future tests).
The third approach, which I have been experimenting with, is this: simply don't use ActiveRecord callbacks. This is something I picked up from Gary Bernhardt's screencasts (which, by the way, are pretty amazing). Instead, define a service class that wraps the act of creating a post. Something like:
class PostCreator
def self.run(attrs={})
new(attrs).run
end
def initialize(attrs={})
#post = Post.new(attrs)
end
def run
if #post.save
make_http_request
return true
else
return false
end
end
def make_http_request
# ...
end
end
This way PostCreator.run(attrs) is the de facto way of creating a post instead of going through Post. Now to test saves within Post, there's no need to stub out callbacks. If you want to test the PostCreator process, there's no magic going on, you can easily stub out whichever methods you want or test them independently. (You could argue that stubbing out methods here is the same as stubbing out AR callbacks, but I think it's more explicit what's going on.) Obviously this only handles post creation, but you could do the same for post updating too.
Anyway, different ideas, pick your poison.
The #set_some_values method here is called when you call #save on the record. So it has nothing to do with the constructor and therefore you don't need to stub User.any_instance -- just make your record and then do a partial stub, as in:
record.stub(:set_some_values)
record.save

Instantiate A Class For Testing

I need to test a method belonging to a service class. This service class has several dependencies in the constructor, some used by this method, some not. If we should not be using a DI container for our unit tests what is the best way to instantiate the service class?
var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2(), etc.);
That's hard to read and seems like a lot of code just to test one method. Things get real messy when some of those dependencies have dependencies of their own.
You should really look at using a mocking framework to isolate your test from the actual dependent objects. I'm assuming you use C# (from the var keyword), so I'll give an example from RhinoMock.
var respository1 = MockRepository.GenerateMock<Repository1>();
repository1.Expect( r => r.SomeMethod() ).Return( someValue );
var repository2 = MockRepository.GenerateMock<Repository2>();
repository2.Expect( r => r.Method2() ).Return( someValue );
...
var service = new Service( repository1, repository2, ... );
repository1.VerifyAllExpectations();
repository2.VerifyAllExpectations();
Using this mechanism you can control how the mock object responds to your class under test and you isolate your test code from related dependencies. You can also test that your class under test is interacting properly with the classes that it depends on by verifying that the expectations that you set up have been met (called).
As for the number of parameters in the constructor, consider providing a default constructor that takes no parameters and having public settors for the dependencies. Then you can use the convenience mechanisms in C# 3.0 for defining them.
var service = new Service {
Repository1 = repository1,
Repository2 = repository2,
...
};
http://www.myjavatools.com/cuecards/refactoring.html
Constructor → Factory Method
if you want more than simple construction
Sometimes (especially if it is testing code) a bit of code reformatting can do the trick. While
var service = new ServiceClass(new Repository1(), new Repository2(), new ServiceClass2());
is definitely hard to read, this:
var service = new ServiceClass(
new Repository1(),
new Repository2(),
new ServiceClass2()
);
seems a bit better (at least to me).