Laravel: What is the best practice in testing controller - php

I'm using laravel 4 and trying to write a test for controller with a mock up of the business logic which pass some fake data.
Then I encounter errors in rendering view due to missing of variables.
First of all, I didn't expect that the view will be rendered, so I didn't care to pass the exact data structure that is needed.
Should I pass the correct data structure to the view or is there a way to stop view from rendering in the test? Which is the better practice and why?
Moreover, after attempting to imitate data structure passing by business logic, there is still error cause by permission of user.
The result temp file of the view has been generated by web user (www-data) and I don't have permission to modify it.
I know, I can just chmod 777, but this is clearly not a good practice, if I have to do that for every time I want to run the test.
Thanks in advance

I suppose your controllers are not messed up. Every logic should be injected through constructor or resolved from the IOC. Mock external classes and bind mocked instances on your test setUp. Facades already have support for Mockery. You can use XXX::shouldReceive().
Also, I suggest you to take a look at Illuminate\Foundation\Testing\TestCase. It has helper methods like assertViewHas, assertSessionHas, assertRedirectedTo etc. With these, testing your controller will be really easy.
After all, best thing to do for you would be reading "Laravel Testing Decoded" by Jeffrey Way. It'a short and amazing book. https://leanpub.com/laravel-testing-decoded

i had a similar problem with the view breaking up while testing. in my case it was a foreach loop, that didn't get the right structure, so i changed my mock to return an empty array, this made the test pass. so this is a possible solution for you i think, though it doesn't mock or just forget rendering the view itself.

Related

Test Driven Development and KISS

For example I want to design a Job entity. Job has a status and I need to mark a Job as done.
I wrote a markDone() method and I want to test it. So to do an assertion I need one more method - isDone(). But at the moment I don't use isDone() method in the my code.
Is it ok to write such a useless methods to please a TDD?
Is it ok to write such a useless methods to please a TDD?
Yes, but maybe not.
The yes part: you are allowed to shape your design in such a way that testing is easier, including creating methods specifically for observability. Such things often come in handy later when you are trying to build views to understand processes running in production.
The maybe not part: What's Job::status for? What observable behavior(s) in the system change when that status is set to done? What bugs would be filed if Job::markDone were a no-op? That's the kind of thing you really want to be testing.
For instance, it might be that you need to be able to describe the job as a JSON document, and changing the job status changes the value that appears in the JSON. Great! Test that.
job.markDone()
json = job.asJson()
assert "DONE".equals(json.getText("status))
In the domain-layer / business-logic, objects are interesting for how they use their hidden data structures to respond to queries. Commands are interesting, not because they mutate the data structure, but because the mutated data structure produces different query results.
If the method has no use outside of testing, I'd avoid writing it since there's probably another way that you can check whether or not the job is done. Is the job's status public, or do you have a method that returns the job's status? If so, I'd use that to test whether markDone() is working properly. If not, you can use reflection to check the value of a private or protected object property.
Can `isDone()' just reside in the test project and not the production code? That way, you wouldn't have useless production code just for the sake of testing.

CakePHP where to put shared code?

I'm developing an application in Cake that heavily interacts with the filesystem. The basic idea is to monitor and index a folder and it's subfolders and files and save meta data for each file in the database. It's working fine so far, but now I got kind of a problem in understanding the MVC mechanics.
I got this heavy FilesController with a lot of functions checking if a file is up-to-date or if it has moved, updating the database entries and so on... Now I want to call some of this actions from a shell/cronjob and I want to call them in the browser too.
I've heard a lot of people complaining about importing controllers in shells and I think I got the idea why this is a bad idea. But now I want to use the same code that interacts with the FileModel directly in a shell and in a controller. Where to put it? What is best practice in this situation? In a component, loading the model? In the controller, importing it in the shell?
Thanks for your help in advance <3
I got this heavy FilesController with a lot of functions checking if a
file is up-to-date or if it has moved,
Wrong place, heavy controllers are definitely wrong. You want fat models, skinny controllers. If there is logic that extracts meta data I probably would put it into app/Utility/FileMetaData or app/Lib/FileMetaData.php and make it a new class. Depending on what it does you might extend the core class Folder or File.
The processing logic for the meta data and reading the folder should go into a model. The model can be used from the shell like in a controller by using the $uses property with an array of models.
To instanitate that class I would use a helper method (I don't mean a view helper by this!) in the model like getMetaDataReader() that returns the instance. The reason for this is to be able to mock the result of that method call in an unit test. Also, if you ever change the class or constructor args you'll have to change only a single place.
Controllers are clearly wrong in shells. There is no request to deal with. Sure technically you can do the stunt and instantiate them there but it is just wrong and doesn't make any sense. If you think you have to or "need" to do so, something is wrong with your application architecture.
You might want to take a look at my FileStorage plugin as well. You can implement an event listener there and when storing a file have the listener automatically process the the meta data.

PHP MVC (no framework), should I be calling a lot of methods in my controller or model?

I've been working on creating my own MVC app in PHP and I've seen a lot of differing opinions online about how exactly this should be set up. Sure, I understand there seems to be a general "It's MVC, it is what you make of it" approach, but I'm running into 2 seemingly conflicting viewpoints.
A little background on my app: I'm using smarty as my presenter and an object-oriented approach. Seems simple enough, but I'm trying to figure out the ubiquitous "what is a model" question.
If I take a look at some tutorials and frameworks, they seem to view the model as strictly a class that inherits DAL methods from an abstract class, with a little bit extra defined in the class itself as your data needs differ from object to object. For example, I might see something like $productModel->get(5) that returns an array of 5 products from the database. So what if I need to query multiple models? Do I store all of the data in the controller or an array and pass that to the view? Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view? This seems bad, especially because I then have to pass in things like "controllerName", "controllerData", and my View::render() method gets hugely bloated with parameters, unless I pass in the controller itself. Maybe I'm missing something here.
Let's say I want to make a login that queries a users table. Login is a model or a controller, depending on certain implementations I've seen online. Some implementations (I'll call this method 1) make a LoginController with method login() that might do a comparison of $_POST and what's returned from the user model instance $user->get(1) to see if a user is validated. Or maybe login() might be a method in a default controller. On the flipside, an implementation (implementation method 2) that resembles more of a Joomla approach would make a Login model and declare all of the actions inside of that. Then any data that needs to get assigned to the view would get returned from those methods. So login->login() would actually check post, see if there's a match, etc. Also the User model would probably be instantiated inside that model method.
My feelings about 1: The controller is fat. Additionally the controller is storing data pulled from models or passing in ten thousand variables. It doesn't seem to jibe with the idea that the model should be passing data to the view that the controller should be blind to. Also, let's say I want to wrap everything that is in a specific model handled by a specific controller in an outer template. I'd have to copy this template-setting code all across my controller functions that interface with this model. It seems grossly inefficient.
My feelings about 2: It doesn't make for having actions that aren't model methods. If I want to go to my site root, I have to make an index model or something that seems like overkill in order to have a model that passes data to the view. Also, this doesn't seem to be a very popular approach. However, I do like it more because I can just do View::render(mymodel->func()) and ensure that the data is going to be passed back just the way I like it without having to crap up my controller with code merging a thousand query results together.
I've waded through far too many religious arguments about this and want to know what you guys think.
I've built my own framework in the past too so I know what you're going through. I've heard the saying "build fat models" and I agree with that -- as long as the main goal is to return data. I considered the controller to be "The Overlord" as it manipulated data and directed where it should go.
For a login controller i might create something it like...
Post URI: http://example.com/login/authenticate
LoginController extends ParentController {
public function authenticate() {
$credential_model = $this->getModel('credentials');
// Obviously you should sanitize the $_POST values.
$is_valid = $credential_model->isValid($_POST['user'], $_POST['email']);
$view = $is_valid ? 'login_fail.php' : 'login_success.php';
$data = array();
$data['a'] = $a;
// .. more vars
$this->view->render($view, $data);
}
}
In my opinion data should always flow from the model -> controller -> view as it makes the most sense (data, manipulation, output). The View should only have access to what it has been given by the controller.
As for this...
Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view?
Well I would imagine you're building a 'base' or 'parent' controller that gets extended off of by your dynamically called controllers. Those child controllers can have properties that are needed for for the view to render -- honestly I'd need an example to go further.
Hopefully this helps a bit. If you ask more specific questions I might be able to give a better thought out opinion.
If you're writing your own app, I think the best solution is to do it yourself and find out.
Ultimately, whatever makes the most sense to you, and whatever makes it easier for you to conceptualize your app and quickly add to or change it, is going to be your best option.
If one way is "wrong", then you'll find out through experience, rather than someone else telling you. And you'll know the entire situation that much better, and know EXACTLY why one way is better.
What helped me when I was writing my own framework in PHP was, strangely enough, CherryPy. It made the concept of an object-oriented web app so simple and obvious, and I enjoyed using it so much, that I modeled the basic structure of my PHP framework to imitate CherryPy.
I don't mean to imply you should learn CherryPy. I mean that simplicity, clarity, and enjoying developing with your own web app go a LONG way.
If I were to give one piece of specific advice, I'd say try to avoid retyping code; write your code to be reusable in as many situations as possible. This will not only be good for your app, but for future apps you may write or work on.
You might check out Eric S. Raymond's Rules for Unix Programming. I think they're definitely applicable here.

Totally failed in OOP/MVC

Ok, it's my fault. I've never ever learned programming at a school and that's why i'm always ending up in a spaghetti code. I've always curious about different patterns and tried to understand them at least in a basic level.
MVC is my worst fear and i think i'll be never able to use it's advantages because of i don't understand it's fundamentals.
My actual question/problem looks like:
The front controller calls a 'Core' class which is doing some initialization then it calls the actual controller with the correct action/parameters. The controllers always extending the 'Core' class so i can acces it's variables, etc. They're working nicely together but here comes my real problem.
Some kind of methods (getting a database entry in most of the cases) are required in different cases. (e.g. a product needs it's manufacturer)
In this scenario i have two (bad) choices:
Inject the required method into the 'Core' class so it's getting bloated over time
Inject the required method into the actually called controller so i will end up a redundant codebase
I see a lot of possible problems in my approach:
Controllers are always extending 'Core' class
'Core' controller holds the database object so without it i cannot access my Db
Database functions (e.g. getting a product) are in the controllers but i cannot access them because they're always calling 'Core' first (extending problem again)
Please tell me:
Where is the biggest problem in my approach and where can i correct it?
Note:
Please don't treat this as a general question, i think this is an answerable thing. If you need some clarification, please ask for it and i'll try to lighten up things.
Thanks for your precious time, fabrik
Your data is represented to your Controller and View through the Model. The Model may be supported by a Repository but depending on the overhead you might want to provide your database access in your Model. The data architecture should be similar to this:
(Repository<===>)Model<===>Controller--->View
Your biggest problem is having the "Core" class, get rid of it asap.
By the way, the FrontController is not the only way to do things MVC things either.
Your second problem is that controller deals with database, it shouldn't. I suggest you use some abstract data layer, which you use only in your models. And controller should deal only with models, it shouldn't care how models get their data persisted and fetched.
Look into using a DI framework to automatically inject an instance of a repository into your controllers (or even better, a proxy class). Try to keep business logic outside of your controllers, but rather, refector it out into a helper or proxy class.
I tend to split my logic up into views => controllers (just for interaction between business later and view) => business logic => models (DTOs) => low-level data access at a minimum.
Also, if you need common helper functionality in your views, perhaps create several extensions to help.

Database calls in Smarty/views/templates

Today at work someone tried to convince me that:
{$obj->getTableInfo()}
is fine for smarty/mvc/templating because it is using an objects method. I argued that because it makes a call to the database it has no place being there and it should be in the controller (we don't actually use MVC). Am I right in my understanding of the logical separations that are used in MVC and generally in templating? Or is there something that I am missing?
You're right. He's wrong.
Database calls, no matter in what form, should live in the controller if you want to do MVC right.
Obviously people piss all over what it should be and do stuff like that, but it's not the correct way.
Well, there are no "official" rules or anything, but I think something like that belongs in the controller. I don't do anything in my view code except display variables, nothing more complex than an if or a foreach-type loop is allowed. Certainly not calling functions that access the database. That should all be loaded by the controller, the view should only decide whether it needs to display it or not.
Depends on its context and scope really.
Is $obj the controller or the model layer? That should answer whether or not it is valid in my opinion.
In response to reading the other answers.
The functions name in itself pertains it to being a simple getter method. It may make a call to the db through a controller layer. Which I would say is ok. Especially if it used some form of caching in memory. (ie the getter is the setter as you only want to cache it when it is used once.)

Categories