I have a thorough ability.rb defined that's working properly. However, when I write a controller spec that sends a request to an endpoint, cancan(can) repeatedly returns a 403.
In my ability.rb in the respective section for handling the endpoint I'm testing, when outputting {Model}.all.to_json it's outputting an empty array.
How can I fix this so that it recognizes the data in my test database, or change my test to bypass this?
The data in the test database is reset on each iteration. If you want to use some specific state (e.g. data), you must re-create that state as part of the test.
Depending on the test framework, use the before or setup hook to create the data you need in the test suite before the test itself is executed.
After going through a deep stare down of my code, I realized that one bit of data I wasn't creating through fixtures was failing validation, thus not being created.
My testing environment was setup properly, but I didn't have a create! call but rather a create, causing it not to be explicit with the validation errors.
Related
I've been leaning some of RoR, and when I got to TDD, stuff started to get more complicated. At some point of my App, I thought it would be better to run my tests over the real data.
Real Data vs Sample Data
Searching the web, I found that tests were not meant to run over real data, but over sample data. But yet I couldn't agree with that.
Let's supose my app had an Alias System. So when you access a random url it figures out what that fragment wants and redirects to the proper canonical url. And let's add that an alias dictionary is stored in some models. How would we test agains that dictionary? Hard code spec files for every alias/keyword?
Sticking with real data
The first two things I've realized, yet very unsurely, is:
Rspec testing environment wouldn't access development model's data.
FactoryGirl rules over my testing database, so it's not my option to populate it.
The best solution I could figure out, as the complete newbie I am, is that I could create some classes in spec/support folder and call them inside my factories so as to get that real data. Those classes have a short sample of my real database info, nested, and so my test can go 'real'.
What can pros around suggest to improve it?
I think you may want to look into building a seeds.rb file to populate your databases. This is usually used to initialize the development database so it can be used in your app (and queried in the rails console), but you can use it to seed your test database as described in this answer.
You certainly should not use your development database for testing. You can either seed the test database, or create factories that reflect various scenarios.
FactoryGirl rules over my testing database, so it's not my option to populate it.
You can use more than one factory to represent a business entity, depending on the scenario under test. FactoryGirl makes this easy by allowing you to nest factories. You can define a factory with a basic set of valid attributes and use that in unit tests. For integration (feature) tests, you can use a nested factory that expands on the basic attributes to implement a particular scenario. You can have as many variations of these implementation-specific factories as you need.
When writing a spec for a Rails model, is there a difference between checking whether the model should be valid, and whether save should be true? I see in other code bases that these two conditions are tested independently, but the Rails API seems to explain that this validation check is ran when save is called.
Is there any condition in which a model could be valid but not save?
Sure, database could be down. A non-validation-related callback could fail.
But the point is that tests should test small isolated bits, so validation logic is tested separately.
I am using Ruby on Rails 3.2.2, cucumber-rails-1.3.0, rspec-rails-2.8.1 and capybara-1.1.2. I have this problem but I started thinking that maybe I'm doing something wrong... mostly about seeding data in the test database for testing purposes. Specifically, my issue is related to how to properly manage data in the test database when I have to test my application.
My doubt is: By seeding data (For Your Information: I use the ROOT_PATH/db/seed.rb file to inject that data) in the test database I'm doing things as they should be done? That is, how should I populate the test database since the data in that database* is required in order to make to properly work my application for testing purposes? Should I populate the test database at all?
In other words, what are best practices to handle database data in test mode (in my case)? And, generally speaking, how the situation should be handled?
***** For example, in order to work my application requires at least data related to an "anonymous" user, to "basic" articles, to "basic" article categories, etc.
You should use one of the following:
Fixtures. See corresponding Rails documentation
Factories. The most popular tool to created/manage factories is FactoryGirl. IMHO that's the best solution.
Make sure data is seeded into test database. See this StackOverflow question.
I had a similar problem, association made it necessary to have a bit of seed data:
Factories will make your tests really slow, they are perfectly OK for single objects, but not for a lot of seed data that has to be created for each test
Fixture Builder - http://github.com/rdy/fixture_builder
I created a bunch of fixtures and just load them from the DB for each test, cut my test time down by 40%. You can also load the seeds file instead.
But be careful, deleting or updating records will create unwanted side effects. Use factories for those specs.
Mock and Stub everything so that your tests rarely touch the DB.
This has become very unpopular, you will eventually get passing specs that don't pick up on your actual errors.
I'm currently creating rspec test cases for a Rails 2.3 application. The problem I'm confronting is that the application has a dependency on data from an external database like this:
Main_User is an external application.
Node_User is the application I'm testing.
When a new Node_User is created, Node_User calls Main_User which creates a user and returns with some data which Node_User uses to create a the Node_User.
Is there any way I can query the Main_User database to verify that the record created there contains the data that is passed to Node_User? Or is there a better way to test this?
Thank you!
Yes, you can theoretically query the remote database if you have access to the user/pass/hostname for that database. (Search for "Rails multiple databases.")
But I wouldn't necessarily recommend taking that approach. Your tests would be modifying the state of the remote database. This strikes me as unsafe. You'll be creating bogus records--and possibly deleting or corrupting data, if your tests do any mass deletes or exercise broken functionality. In other words, your tests may do bad things to a production database.
Therefore, I would recommend mocking the remote database in some way. One option would be VCR. It's really cool, but it would require you to operate on the remote database at least once, because it has to record the first run. Another option is to use one of the tools underlying VCR, such as FakeWeb.
Of course, this only tests the Node_User side of things. You said you also need to verify that the remote record is correct. To do that, I would recommend writing tests on the Main_User side. Such tests would simulate an incoming RESTful request from Node_User and verify the correct result.
That only works if Main_User is your application. If it's a third-party service, then there may not be a safe way to test it. You may just have to trust its correctness.
I'm currently writing specs for my Ruby on Rails application using Rspec and capybara with selenium to drive the browser.
While executing one of the specs I want to change the value of a session variable.
Eg: I want to set session[:location]="US" so that I can test my application while all values are seen in $. How do I go about it?
Capybara/Selenium specs are for acceptance testing. You shouldn't do any kind of mocking, stubbing or...changing session values directly. You should interact with your application from within the spec just like a normal user would do in the browser.
How the location is being set in your app? Can the user set it manually? If yes, you should do it in the spec in a before block.
It's not exacly as you say.In Cucumber scenario we have chance to test some cases, and you must have a changes to create some background for that cases like create some user in Given block or add somethink to db and etc. Sessions is the same resoures like db and i thnik you should have the chance to prepare it for tests. No metter how strong it's connected with end-user.
Imagin that you create some multistep application where you presist some info beatween steps in session. Your client couldn't even imagin his reservation wihout any of this few steps. So from this point of few it's seems to not make any seans to create acceptance test for every step separatly. But after moth your client want's add some extra super user-frandly validation on 4th step. Now he is only intresting in this side and this validation. Probably he could deal with other extra 4th steps but why? He already saw all this staff and accept it.
What you think about this point of view?