Testing in rails without factory girl - ruby-on-rails

I have short question but for me important. What is better. Should we use something like factory_girl in our tests or better solution is to use simply services witch we use in our system? What is better to setup initial state of our tests.
Edit:
Thanks for answer. I have found interesting blog post in this subject:
http://blog.arkency.com/2014/06/setup-your-tests-with-services/

I think the answer in 99,9% will be: Use factories.
Here is just my thoughts:
It all depends on the services you are talking about.
If your service is quite transparent (just creates instances and assigns some fields without any logic) then you may use it in tests. Note that in this case it is likely that your service is almost a factory.
If a service contains some logic or it will ever be changed it is better to test it in isolation as well as the code that use this service. And that is when factory comes.

Related

Structure of BDD tests

I'm digging into Capybara and rspec, to move from TDD to BDD.
My generators make a whole lot of directories and spec tests,
with directory structure similar to this:
spec
controllers
models
requests
routing
views
I think that most of this is TDD rather than BDD. If I read here:
"A great testing strategy is to extensively cover the data layer with
unit tests then skip all the way up to acceptance tests. This approach
gives great code coverage and builds a test suite that can flex with a
changing codebase."
Then I figure that things should be quite different
something on the lines of:
spec
models
acceptance
Basically I take out controllers, requests, views, and routing to just implement tests as user case scenarios in the acceptance directory with Capybara, Rspec.
This makes sense to me, though I'm not sure if this is the standard/common approach to this.
What is your approach?
Thanks,
Giulio
tl;dr
This is not a standard approach.
If you only test models and feature specs... then you miss out on the bits in the middle.
You can tell: "method X broke on the Widget model" or you can tell "there's something wrong while creating widgets" but you have no knowledge of anything else.
If something broke, was it the controller? the routing? some hand-over between the two?
it's good to have:
extremely thorough testing at the model-level (eg check every validation, every method, every option based on incoming arguments)
rough testing in the middle to make sure sub-systems work the way you expect (eg controllers set up the right variables and call the right templates/redirections given a certain set of circumstances)
overall feature testing as smoke-tests (eg that a user can go through the happy path and everything works the way they expect... that if they input bad stuff, that the app is throwing up the right error messages and redisplaying the forms for them to fix the problem)
Don't forget that models aren't the only classes in your app.. and all classes need some kind of testing. Controllers are classes too. As are form and service objects, mailers, etc.
That said - it's common to consider that view-tests are going overboard. I'm also not keen on request-tests our routing test myself (unless I have something complex which I want to work right, eg lots of optional params in a route that map to interesting search-patterns)

Cleanly Setting up multiple models in FactoryGirl for a test/spec

I have been picking up on Rails best practices and learning to write good tests for my rails application.
I am using rspec + FactoryGirl to test at the moment.
For a while I was writing basic model and controller specs which usually required to set up only a couple of models and associations.
Now I have a Model with a complex algorithm which does a lot of calculations based on different models.
To test this method, I almost need all the models of my app to exists in test database with all associated relationships built between them.
Now things are getting overwhelming. I need to keep track if all factories are correctly referencing each other. Also I need to verify if all factories have been created properly.
Also a lot of FactoryGirl.create(:model) calls in my before(:each) method.
I have a feeling that I am not doing things right. What is the best way to go about this situation? Most books and examples only cover only the very basic cases.
Any pointers ideas and approches are welcomed.(Hope this question is not too wide in scope)
Example:
My application has multiple projects. Each project has_many indexes , companies and mastertags. Each company has_many channels. Every channel has_many channel_tag_weights across different mastertags. Also every channel has_many Rawdatas.
This could be an example of a minimum model setup required.
I wrote a gem for this called stepford.
In your gemfile:
group :test do
gem 'stepford'
#...
end
Then bundle install.
Back up your factories.rb or existing multiple files containing factories. In fact, you need to move them out of the way because if it loads other factories, that can interfere.
Then: bundle exec stepford factories --path spec (if want to put factories.rb in the spec dir- there are other options to create a factory per model, etc. though).
We had problems with dependencies that needed to be created where there were foreign key constraints. In the process, I wrote the modelist gem that can help identify circular dependencies, which you might want to check out and run if you are working with legacy data. And Stepford's deep creation methods get around these issues. But, we've started to steer away from using the deep_* methods of Stepford, even though we still use it a little. It is just better to be specific about what you are doing and use factory girl directly, even though it can make test code more brittle and overly-complicated looking.
You could also look at fixtures, or machinist. It really just depends on what you need.
If you need to actually create all of the code for the models, that is a different problem. I wrote a script to generate models for the local legacy schema (which was quite large), and it did help, but it took months of iterative work. The thing is that the schema itself is not (necessarily) the definitive description of the associations or setup in the models. To give you an idea of what I'm talking about, I wrote a number of gems to assist with some of the things that legacy apps, etc. were doing/had done that we had to deal with like undeletable, activerecord-define_nils, mark_only, activerecord-custom_timestamps, activerecord-native_db_types_override, and some others in earlier attempts. And we use some great gems that already existed like composite_primary_keys and foreigner.
Some other things we grappled with was using of MTI (multiple table inheritance), which despite a few gems out there that try to help, we ended up handling it ourselves in our models via hooks, etc. And we merged some schemas (not something to take lightly, but the divisions weren't necessary, and apartment, second_base and similar gems would be adding to the complexity, not even considering inability to join, use normal queries).
Please note: in our case we had a lot of tables. If you don't have quite as many, you still might use Stepford to maybe make the first creation of factories a little easier, but then I think you will be ok.
Whenever I get into this type of situation, I try to make sure that all of my FactoryGirl models take advantage of FactoryGirl's built in association methods:
https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations
That way the associated models that are required in order for a single model to validate properly are present. FactoryGirl will go through the process of populating your database with the extra test data.
Because you are using has_many associations, you will want to study the after(:create) method of the factory definition in order to set up your associations properly. This will also allow you to create definitions specific to these deeply integrated specs, and keep simpler factories independent for the simpler specs.
If you are testing only a method, that is unit testing.
I don't think you need to setup too many things.
A method has input and output, you just feed it with examples of inputs created by you manually, and expect it to generate right output.
If a method has too much things to concern, you can split it into several methods, and unit testing each one.
When times for integration testing, the whole environment should be setup. And yes, you need to prepare all the factories needed.

Rails RSpec, how does it apply in such a case?

i'm daily in the process of learning new things about Rails (started learning 2 and now migrating to 3 concepts). As a project with Rails, i'm coding a browser game. Till now, i've been using fixtures to load data to my database and i've creating a custom task to recreate the db, load fixtures etc every time i need to. I have to say that i like this approach because i can easily define my monsters with weapons, bonuses etc through active record associations in features.
However, i see that people use a testing environment like RSpec for that kind of things. Although i see that RSpec is used as a language to define proper behaviour, i don't clearly see how it could help me. But since i like to do things the correct way, i'm pretty sure that there is much more for me to understand and read about it.
Therefore, i would like to ask for a solid example of how RSpec could be helpful. For instance, let's say that a user creates an alliance. Through my code, i'm checking whether this user already has an alliance, whether an alliance with that name exists, whether he has the money to create this alliance and more. Where would RSpec fit here ? What would a nice usage example be ?
Moreover, is fixtures done using RSpec in another way ?
I already know that Rails has many great programmer conveniences and i would like to harvest this one as well. But i'm still ignorant about RSpec. That is why i would appreciate some useful insight. Thank you :)
Rspec is a testing framework. It allows you to write automated pieces of code that verify that your code is actually working. For example, you could write a test to make sure that no two alliances have the same name:
describe Alliance do
it 'should not have the same name as another alliance' do
first = Alliance.create :name => "Test Name"
second = Alliance.build :name => "Test Name"
second.should_not be_valid
end
end
This code would then verify that no two alliances can have the same name - it's a way of testing that your code is actually working.
Fixtures, Factories, Mocks and Stubs are all ways of creating temporary data that can be used in tests. RSpec can use Fixtures, but it doesn't require them either. If you want to load test data into your database you can do this in whichever method best suits your needs to perform tests.
Some other testing frameworks are Cucumber, TestUnit, MiniTest and Shoulda. You should be using one already to write tests for your code. You can also read up on the others to find out which framework best suits your needs.

Rails Fixtures vs. Mocks

I'm developing a Rails app, and I was just talking with my colleague that we have a mix of fixtures and mocks in our tests, which we're doing using cucumber and Rspec. The question would be: when should each one be used?
I would use a mock object when using the real object is impracticable/not necessary. Lets say for example you need to call some remote API such as an address finder via zip code. You would probably want to mock the object so the calls on it aren't actually made each time you run your tests. There are other reasons too such as improving speed, asking for data that changes where you need an exact response or perhaps it doesn't exist yet. It allows you to test things in isolation as you can determine that when you call these methods on this mock object you will get this back and you don't actually need to run the code as for this test it's not important.
If you use fixtures you will have a real object and the methods etc will be called and their code run, unless of course you stub the methods out, which is something for another question.
Hope that helps a little. There is a good peepcode (http://peepcode.com/products/rspec-mocks-and-models) on mocking and stubbing, maybe check it out.

Rails: When a model? When a lib?

I'm making a little message sending module. It'll handle queuing messages from a request to be picked up by a background worker to send email/SMS (or log appropriately for testing).
Question: is this a Model (under /app/models) or a lib (under /lib).
I'd like some religion on this.
Theory A: (My current theory) Unless you're subclassing ActionMailer::Base or ActiveRecord::Base, etc, your code should go into lib.
Theory B: (Theory I'm leaning towards) Things that are application-specific should be in model. Anything that could be of general use should be in lib.
Theory C: only "data models" should be in 'models'. ActionMailer subclasses break this rule, though.
As far as I know, either way it'll work fine, but I'm looking for any subtle functional or philosophical reasons for one vs. the other.
Thoughts?
Whether or not messages inherit from ActiveRecord or ActionMailer, you likely want a model for any objects that your views and controllers interact with. In your case, they will handle instances of the Message class -- you want a model for that.
As for the message sending module -- extracting out to a library is great if you plan to reuse the code elsewhere where you can just include the module in any class.
Since this is just a "little" message sending module, you might want to start in the model and eventually extract out to a separate module if it could be useful elsewhere or your model gets too messy.
You should probably think more in terms of the underlying business here. Models, as their name suggests, are here to represent (model) some real-world system or process. So, the rule of a thumb should be this: Does this entity play any role in the system I'm trying to express in my application? If the answer is positive then the entity is a good candidate for being a model. However, it'd be perfectly OK to implement the core functionality of your messaging module in some separate library for later reuse and just include it in the model.
I like the 'Data Model' Theory and I try to stick to it when I can, but I think Bensie and Milan have the right idea. If you have views and controllers associated with it, it should be with models. If you are only referencing the functionality from within another class, put it in the lib.

Resources