mocking randomnly generated data in rspec - ruby-on-rails-3

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.

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.

Custom strategy for warden not getting called

I am trying to use a different warden strategy to authenticate my action cable end points.
But the strategy is not getting called. I tried to place warden.authenticate!(:action_cable_auth) in a controller to test but none of the debug statements are getting printed on console.
Below are the relevant part of the code.
config/initializers/warden.rb
Warden::Strategies.add(:action_cable_auth) do
def valid?
#check if its a websocket request & for action cable?
#Rails.logger.error request.inspect
p 'checking if strategy is valid?'
true
end
def authenticate!
p 'unauthenticate the user'
fail!('user not active')
end
end
in my controller
warden.authenticate!(:action_cable_auth)
Assuming that you are setting your initializer in the proper place, please recall that if your session is already instantiated somewhere else (for example if you authenticate the user at the point your action is being called, then your strategy will never be called.
This is basically how warden works: if some valid? strategy returns a success! then no other will be called as soon as any authenticate! method in the list of strategies is successful.
Please also be sure that if you want your strategy up the list of strategies to check you may need to also shift it up on the list, such as:
manager.default_strategies(scope: :user).unshift(:action_cable_auth)
Where the manager is your Warden::Manager instance. The scope may also be optional (this is an example where the user scope is used alongside Devise), but you may check your instance .default_strategies to figure out where it is and where you want it.

Lumen - seeder in Unit tests

I'm trying to implement unit tests in my company's project, and I'm running into some weird trouble trying to use a separate set of data in my database.
As I want tests to be performed in a confined environment, I'm looking for the easiest way to input data in a dedicated database. Long story short, to this extent, I decided to use a MySQL dump of inserted data.
This is basically my seeder code:
public function run()
{
\Illuminate\Support\Facades\DB::unprepared(file_get_contents(__DIR__ . '/data1.sql'));
}
Now here's the problem.
In my unit test, I can call the seeder, but :
If I call the seeder in the setUpBeforeClass(), it works. Although it doesn't fit my needs as I want to be able to invoke different sets of data for different tests
If I call the seeder within a test, the data is never inserted in the database (either with or without the transaction trait).
If I use DB::insert instead of ::raw or ::unprepared or ::statement without using a raw sql file, it works. But my inserts are too complicated for that.
Here's a few things I tried with the same results :
DB::raw(file_get_contents(__DIR__.'/database/data1.sql'));
DB::statement(file_get_contents(__DIR__ . '/database/data1.sql'));
$seeder = new CheckTestSeeder();
$seeder->run();
\Illuminate\Support\Facades\Artisan::call('db:seed', ['--class' => 'CheckTestSeeder']);
$this->seeInDatabase('jackpot.progressive', [
'name_progressive' => 'aaa'
]);
Any pointers on how to proceed and why I have different behaviors if I do that in the setUpBeforeClass() and within the test would be appreciated!
You may use Illuminate\Foundation\Testing\RefreshDatabase trait as explained here. If you need something more, you can override refreshTestDatabase method in RefreshDatabase trait.
protected function refreshTestDatabase()
{
parent::refreshTestDatabase();
\Illuminate\Support\Facades\Artisan::call('db:seed', ['--class' => 'CheckTestSeeder']);
}

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

Mocking a Rails application object with mocha

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)))