different behavior of method when immediately accessing the results - ruby-on-rails

I have a class method Juxtaposition.generate_for(position) on a class that I am calling from a spec. The method sets up a map reduce and calls it map_reduce(map, reduce).out(merge: "juxtapositions")
The position variable is defined in a let prior to the it block.
When executing if I simply call the function above (which is really only calling a map reduce on data related to the position) then tests like below fail:
Juxtaposition.count.should eq 1
Juxtaposition.first.value.should eq values
However, if I call
Juxtaposition.generate_for(positions).first["value"].should eq values
prior to the two tests then they both pass. The above two tests also pass when I use pry and call the generate_for method from there.
Is there some strange behavior of map reduce in mongoid that I should be aware of? Or, is there some way to force the results into my later queries.

Solution was simple enough. I just need to make sure to call find on the call to map reduce.
More specifically:
map_reduce(map, reduce).out(merge: "juxtapositions").first
or
map_reduce(map, reduce).out(merge: "juxtapositions").to_a
Without to_a or first the actual map reduce doesn't execute it seems, even if it's meant to be stored in another collection.

Related

OCMock: OCMVerify times gets wrong count when using OCMPartialMock

OCMock Version: 3.6
Hi, I use OCMPartialMock to mock a config object. When I use the reference to the real object, it is right to verify the times the function networkStatusCacheTime in the object is called.
This is the screenshot -verifyInvocation:withQuantifier:atLocation: called when it is matching invocation to count. Only one invocation ocmock_replaced_networkStatusCacheTime can match.
But the test failed when I use the reference to the mock object.
OCPartialMockObject(NATritonConfig): Method networkStatusCacheTime was invoked 2 times; but was expected once.
Invocations networkStatusCacheTime and ocmock_replaced_networkStatusCacheTime both match by this time.
Is it different using the real object from the mock object? Maybe is it wrong the way I used?
This is a bug. I see you have opened an issue already: https://github.com/erikdoe/ocmock/issues/444

How can I get access to the class instance that is rendering my view in a test?

I'm trying to test a rake task which scrapes my site and pushes the content to an elasticsearch server; the task works fine. However the test is failing because in one view I randomly pick some values like this:
[:breast,:ovarian][rand(2)]
(rand * 4)-2
rand(Date.new(2006)..Time.now.to_date)
Which means I need to stub rand. In order to stub rand I need access to the class-instance that is calling it, which in this case is whatever class is rendering my view. Calling puts self.class Just returns Class and an id, so how can I get ahold of the instance in order to stub it?
I could pass these values into the view from the controller as instance variables, if getting ahold of the controller would be easier.
long story short: it would be better to extract the offending logic and place it in a helper. This way you will be able to stub it easily, and even unit-test it if needed. Moreover this improves the overall quality of your code (no logic should belong to the view).
also, rand is a method from Kernel, so it is already "stubable"

RSpec stubbing a complex Rails result to test one nested field

I'm using RSpec's stubbing functionality to stub a where() call on an object:
allow(ActiveRecordObject).to_receive(:where).and_return(result)
This works great when the expected result is simple, such as an instance of the ActiveRecordObject with a field set to a certain value.
However, the result I want to test is more complex. I'm intending to test a value set on another ActiveRecordObject that is nested three deep through Rails hasMany functionality and this is more tricky. For example, I'd like ...
expect(result[:child_object][:test_target][:field]).to eq(value)
... to work as a test after the function that I'm testing is called.
The way I've attempted and so far failed to achieve this is by copying the structure of the object so the result is a considerably more complex.
What I'd like to do is stub the actual call (or value, if a call isn't really made) to test_target so when the call is made a much more simple stub is hit. This seems to me to be better as it creates less brittle, easier to understand code.
I've also tried stubbing a where() method on the class TestTarget.
What is the correct way to configure values in linked ActiveRecord objects in RSpec so that when the parent object is called the resulting structure contains a value hard-coded for test.
Also, is this possible without using Factory Girl (tech leads at work have decided that we want to move away from using FactoryGirl)

call arbitrary chained methods on wrapper class

I'm creating a wrapper class for an API because my application will need to call it with different credentials at different times. I started off passing the wrapper a method and arguments and then doing (basically) this when calling it
call
set_credentials
TheAPI::Thing.send(method, args)
ensure
reset_credentials_to_default
end
HOWEVER, I realized that a challenge here is if I need to chain methods; this way I can only call one at a time; so for example I wouldn't be able to to TheAPI::Thing.find(id).delete. (At least, not without re-calling the credentials setter, which is undesirable since I have to fetch a token).
Is there a way using ruby to collect the methods/args being chained onto an object? Or would I simply have to pass in some ugly ordered set of things?
EDIT: Surely activerecord's query builder does something like this, collecting the chained methods before returning, and then after they're all collected, ensuring that as a final step the query is built, called, and returned?
the way to do this is to define a proxy object and to pass that around instead of the actual thing.
In the object itself, hold a reference to the Thing and override method_missing: http://ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing
In the method missing do the thing you are doing today. In a nutshell this is what ActiveRecord is doing.
As far as chaining things, I don't believe it would be a problem as methods that can be chained usually return references to self. When you call the 2nd method in the chain, you actually have done the work for the first one and have an object that has the 2nd method in the chain. The only trick you need to pay attention to is that you want to return a reference to the proxy class that encapsulates the thing instead of the actual return of the thing if you want the chaining to succeed.
Give it a shot and ping me if you run into trouble and I can spin up a fully working example.

Does "where" loads data before setup method executes?

I want to construct where conditions based on setup data. But seems like where executes before setup method so I'm getting null object. I'm I right and how can I construct where data based on my setup data?
In short, you can't. The where block must run before the setup block/method for reasons discussed on the mailing list (http://forum.spockframework.org). However, a where block may refer to #Shared variables, which can be initialized directly or in setupSpec(). If necessary, you can write multiple spec classes with different setupSpec() methods and keep them all in the same file.
Often, an alternative is to turn things around and use simple values (e.g. strings and numbers) in the where block, from which more complex objects are constructed in the setup block.

Resources