Play framework testing controller method - unit-testing

I have a controller method that fetches data to render(fetched data) a HTML view of the same. I wanted to write a test to ensure the jpa model is queried correctly. However I am not finding a way to intercept what is being passed into render().
Can someone please let me know if there is a way to get what is passed into render from a test case. If not should I move this code/line into a different class that I can test easily.
Thanks

I know it's not exactly what you want but you could just write some selenium tests that will confirm whether the controller is rendering the correct data in the template. (see: http://www.playframework.org/documentation/1.2.4/guide10#selenium)
Also writing a Functional Test may help (see: http://www.playframework.org/documentation/1.2.4/guide10#controller)

Could you see if the Play Response object i.e. the out contains your expected value?

Related

mapbox-gl - how to instantiate a Map for a simple test

I'd like to start by asking Mapbox - please - to put documentation on their site that explains how to set up and start doing a simple test. There are many tests in their code on Github, but after days of reading and attempting to test I have failed to understand how they work.
I have a very simple method that:
updates some geoJson with some new coordinates and a new heading (rotation) for a marker.
uses setSource to set the changed Json to the Map
I would like to run my little method in a test and then check that the new coordinates have arrived in the Map.
Should be a piece of cake!
Now a Map needs a browser or similar. Yes, there's jsdom, which is almost certainly what is needed, but I have not discovered how you give the dom to the Map.
If I try to instantiate either window, which I found in mapbox-js utils, or Map, I get
ReferenceError: self is not defined. - 'self' appears to be the window object.
I use mocha, with babel 7, for what it's worth, but I think that all I need is to solve the mystery of setting up a Map instance so that I can then interrogate it.
Any help would be gratefully received.

Proper way to seed routes for view spec

I am testing my views with RSpec. Due to some changes, there is now a call to url_for in the view and all the spec that I wrote for show actions are failing:
No route matches {:controller=>"events", :action=>"show"}
The :id part is missing and because of that the call fails.
(I know that I can just stub that failing method call)
The only thing I found is pretty old and looks like a bad workaround. Also the RSpec documentation does not show something helpful.
Is there a proper way to tell RSpec that it should be on something like events/123?
Some more context:
In the view
I call a helper, something like this:
def some_helper_method
url_for(only_path: false)} + "something_else"
end
The call to that method fails with
Failure/Error: render
ActionView::Template::Error:
No route matches {:controller=>"events", :action=>"show"}
I'm currently fixing it by stubbing the call to that method view.stub(some_helper_method: 'SOME_URL')
Okay, I think I found your answer. I cloned your repo and debug a lot =P until I found that you need to infer the desired parameters in your view spec, since rspec-rails only provides the :controller parameter for the view being rendered. Well, in an attempt to understand better what the issue is, I found this explanation in the rspec-rails documentation:
View specs infer the controller name and path from the path to the view template. e.g. if the template is "events/index.html.erb" then:
controller.controller_path == "events"
controller.request.path_parameters[:controller] == "events"
This means that most of the time you don't need to set these values. When spec'ing a partial that is included across different controllers, you may need to override these values before rendering the view
In other words, the previous link that you posted still works and is still the solution for the parameters "issue" in your view spec. You can follow the discussion about the topic in this PullRequest thread.
So, the conclusion is that if you really don't want to stub out your call to url_for helper (or the helper that is calling it), you need to supply the desired :id parameter since there's no route for any show action without an :id param (as pointed out by you). Our final result (tested) is indeed:
controller.request.path_parameters[:id] = event.id
If this a workaround ? I really don't think so, since rspec-rails itself is internally using this feature to provide the :controller param.
I'm sorry I couldn't be more helpful before, but I think that this closes all of our main doubts.
My opinion ? If you really don't need to make any assertions based on the url_for behavior (or any helper behavior for that matter), just stub it, since it is expected to already have been tested in isolation. Otherwise, use the :id param, and don't worry about it. It is not a workaround.
Cheers friend !
If you will face the id problem the try this in your route.rb
get "events/show/:id", :to=> "events#show"

Unit Testing basic Controllers

I have a number of simple controller classes that use Doctrine's entity manager to retrieve data and pass it to a view.
public function indexAction() {
$pages = $this->em->getRepository('Model_Page')->findAll();
$this->view->pages = $pages;
}
What exactly should we be testing here?
I could test routing on the action to ensure that's configured properly
I could potentially test that the appropriate view variables are being set, but this is cumbersome
The findAll() method should probably be in a repository layer which can be tested using mock data, but then this constitutes a different type of test and brings us back to the question of
What should we be testing as part of controller tests?
Controller holds core logic for your application. Though simple "index" controller actions don't have any specific functions, those that verify/actively use data and generate viewmodels have pretty much the most functionality of the system.
For example, consider login form. Whenever the login data is posted, controller should validate login/password and return: 1) to index page whenever logins are good. Show welcome,{user} text. 2) to the login page saying that login is not found in db. 3) to the login page saying that password is not found in db.
These three types of outputs make perfect test cases. You should validate that correct viewmodels/views are being sent back to the client with the appropriate actions.
You shouldn't look at a controller like at something mysterious. It's just another code piece, and it's tested as any other code - any complicated logic that gives business-value to the user should be tested.
Also, I'd recommend using acceptance testing with framework like Cucumber to generate meaningful test cases.
Probably the controller is the hardest thing to test, as it has many dependencies. In theory you should test it in full isolation, but as you already seen - it has no sense.
Probably you should start with functional or acceptance test. It tests your controller action in a whole. I agree with previous answer, that you should try acceptance testing tools. But Cucumber is for Ruby, for PHP you can try using Codeception. It makes tests simple and meaningful.
Also on a Codeception page there is an article on how to test sample controllers.

How to test save functions in CakePHP Models?

Just writing some tests for my CakePHP application and I am currently trying to work out the best way to test some functions in my models which end up saving data.
Should I just assertTrue or should I pull the data out of the database and assert the expected result against what is in the database?
There are some values that I have to generate programatically based on the users input so need to be sure they are write. Should I do a find operation within the test and check that the results of that are what I expect?
Use one of the expects to check what you save method returns. I assume you're not talking about save() because that is already tested within the core. So expect in your test whatever your method should return and see if it passes.
And yes, you can do a find within the test to check if your record was saved with the correct values. So find() it and expectEqual() on the result to whatever you expected.
By the way, it's always good to check the core tests to get an idea of how to test certain things or use mock objects. :)

Can a fixture be changed dynamically between test methods in CakePHP?

Is it possible to have a fixture change between test methods? If so, how can I do this?
My syntax for this problem :
In the cakephp framework i am building tests for a behavior that is configured by adding fields to the table. This is intended to work in the same way that adding the "created"
and "modified" fields will auto-populate these fields on save.
To test this I could create dozens of fixtures/model combos to test the different setups, but it would be a hundred times better, faster and easier to just have the fixture change "shape" between test methods.
If you are not familiar with the CakePHP framework, you can maybe still help me as it uses SimpleTest
Edit: rephrased question to be more general
I'm not familiar specifically with CakePHP, but this kind of thing seems to happen anywhere with fixtures.
There is no built in way in rails at least for this to happen, and I imagine not in cakePHP or anywhere else either because the whole idea of a fixture, is that it is fixed
There are 2 'decent' workarounds I'm aware of
Write a changefixture method, and just before you do your asserts/etc, run it with the parameters of what to change. It should go and update the database or whatever needs to be done.
Don't use fixtures at all, and use some kind of object factory or object generator to create your objects each time
This is not an answer to my quetion, but a solution to my issue example.
Instead of using multiple fixtures or changing the fixtures, I edit the Model::_schema arrays by removing the fields that I wanted to test without. This has the effect that the model acts as if the fields was not there, but I am unsure if this is a 100% test. I do not think it is for all cases, but it works for my example.