I'm trying to write some unit tests for a brand new mini app. I usually write functional tests so this is me branching out to try and do it properly with mocking and stubs and all those things that make it just about the code.
The model looks like this :
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Auth;
class myModel extends Model
{
public static function getUser()
{
$user = \Auth::user();
return $user->adldapUser->cn[0];
}
}
And the test :
class MyModelTest extends TestCase
{
public function testGetUser()
{
$mockResult = new StdClass();
$mockResult->adldapUser = new stdClass();
$mockResult->adldapUser->cn=array("test");
$auth = $this->getMock('Auth');
$auth
->method('user')
->will($this->returnValue($mockResult));
$this->assertEquals('test',\App\MyModel::getUser());
}
}
But when I run the unit test I get the following error message :
There was 1 error:
1) MyModelTest::testGetUser ErrorException: Trying to get property of
non-object
/home/aidan/web/vagrant-web-dev/src/apps/orcid/app/MyModel.php:61
/home/aidan/web/vagrant-web-dev/src/apps/orcid/tests/MyModelTest.php:18
and if I post out $user it's NULL.
What am I doing wrong here?
Here I go again answering my own question half an hour after asking it.
For prosperity's sake I'll leave it here.
The answer was in this post here : https://stackoverflow.com/a/17602763/808124
So I replaced the $this->getMock with
Auth::shouldReceive('user')->once()->andreturn($mockResult);
Working
I use it this way:
$user -factory(User:class)->create();
\Auth::shouldReceive('guard')->andReturnSelf()
->shouldReceive('user')->andReturn($user)
->shouldReceive('check')->andReturn(true);
Related
How to call a model in another controller?
I explain myself, I created a controller and I try to call another model in this controller, but I have the error "Error: Class not found".
You can see the code of my controller "Adserver" trying to call the model "Zone"
<?php
declare(strict_types=1);
use Phalcon\Mvc\Model\Zone as Zone;
class AdserveurController extends ControllerBase
{
public function indexAction()
{
$id_zone= 1;
$zone = Zone::findFirstByid_zone($id_zone);
if(!zone){
$this->flashSession->error('erreur id');
return $this->response->redirect();
}
print_r ($id_zone);
$zone = Zone::findFirst($hauteur);
if(!zone){
$this->fashSession->error('erreur hauteur');
return $this->response->redirect();
}
$zone = Zone::findFirst($largeur);
if(!zone){
$this->fashSession->error('erreur hauteur');
return $this->response->redirect();
}
}
}
On top of my controller, I tried the "use Phalcon\Mvc\Model" and the error persists.
My phalco version is 4.0
Could someone help me on how to call two models in a separate controller?
Thanks.
I call multiple models from withing various controllers all the time and don't have to declare "use Phalcon\Mvc\Model\Zone as Zone;" at the top.
How is your Zone model file defined?
if other_model has relation with Zone (defined in model) then :
Zone->other_model->field;
else in head of file
"use Phalcon\Mvc\Model*other_model*;
Try to define the namespace in your model, like:
// app/models/Zone.php
<?php
namespace MyApp\Models;
use Phalcon\Mvc\Model;
class Zone extends Model
{
public function initialize()
{
$this->setSource('zone');
}
}
Then in your loader:
<?php
use Phalcon\Loader;
$loader->registerNamespaces(
[
'MyApp\Models' => 'app/models'
]
);
$loader->register();
Then in your controller:
<?php
use MyApp\Models\Zone;
Your current indexAction should work, but beware of what I commented to you regarding fields with underscores:
$zone = Zone::findFirstByid_zone($id_zone); //won't work
$zone = Zone::findFirstByIdZone($id_zone); //works
Since you commented that you are a beginner, I would recommend you to review the MVC examples for Phalcon projects: https://github.com/phalcon/mvc So you get acquainted with namespaces in your app.
Also, if you are working on a large application, it's better that you register namespaces than directories for performance reasons, as detailed in the Docs: https://docs.phalcon.io/4.0/en/loader
Ps. Reviewing indexAction there are some parameters that are not defined, like $hauteur and $largeur. Since $zone still is not working, these issues are still not visible --but they'll show up after zone is working.
I have write my code to instantiate Eloquent Capsule/Manager using slim DI like this
$container['db'] = function ($c) {
$settings = $c->get('database');
$db = new \Illuminate\Database\Capsule\Manager;
$db->addConnection($settings);
$db->setAsGlobal();
$db->bootEloquent();
return $db;
}
And I have my route like this
$app->get('/adduser', function() {
$user = new Users;
$user->name = "Users 1";
$user->email = "user1#test.com";
$user->password = "My Passwd";
$user->save();
echo "Hello, $user->name !";
});
When I run the route in browser it will produce error in web server error log
PHP Fatal error: Call to a member function connection() on a non-object in /home/***/vendor/illuminate/database/Eloquent/Model.php on line 3335
In my opinion this is happened because the Eloquent Capsule/Manager is not triggered to be instantiate by DI.
I found a solution to solve this by declare the Model with custom constructor like this
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Capsule\Manager as Capsule;
class Users extends Eloquent {
protected $table = 'users';
protected $hidden = array('password');
public function __construct(Capsule $capsule, array $attributes = array())
{
parent::__construct($attributes);
}
}
But I don't think this is a clean solutions, because I have to rewrite all my Models using custom constructor.
I need help to find solutions for my problem.
I try to use code below:
$app->get('/adduser', function() use ($some_variable) {
// create user script
});
but so far I don't know how to trigger $container['db'] using this method. I really appreciate a help here.
It's probably not a good idea to inject your capsule manager into each model.. As you say yourself, that's going to be a pain to manage.
Have you tried this code outside of the closure? ie. in the bootstrap part of your app..
$db = new \Illuminate\Database\Capsule\Manager;
$db->addConnection($settings);
$db->setAsGlobal();
$db->bootEloquent();
The setAsGlobal function makes the Capsule Manager instance static, so the models can access it globally.
Just to note, convention is to name your model classes in singular form. ie. User rather than Users.
I have built laravel applications in Laravel 4 and Laravel 5, but I decided this time to write all my tests first, having never previously written tests at all for trivial apps.
Here is my Account class - for illustration
class Account extends Model
{
protected $customer_id;
protected $bookmaker_id;
protected $balance;
protected $profit;
public function __construct($customer_id, $bookmaker_id, $balance, $profit) {
$this->customer_id = $customer_id;
$this->bookmaker_id = $bookmaker_id;
$this->balance = $balance;
$this->profit = $profit;
}
}
So all my unit tests run fine:
My route is set up correctly to the page I want to display
Route::get('/accounts', 'AccountController#index');
but this is where it goes wrong. Actually trying to run a page to get a list of accounts is troublesome. I know there is more to do with the controller class but here is what I have.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Account;
class AccountController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$accounts = Account::all();
return view('account.index', compact('accounts'));
}
}
Then I get this error -
ErrorException in Account.php line 14:
Missing argument 1 for App\Account::__construct(), called in /Applications/MAMP/htdocs/mb-app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 665 and defined
Can someone tell me how I should be setting up my controller please? Until I added the __construct() for my unit tests this was all going ok.
Thanks.
By using __construct, it expects arguments any time you initialize it. So instead, you'd use
$accountModel = new Account($customer_id, $bookmaker_id, $balance, $profit);
$accounts = $accountModel->all();
If you want to use those variables for creating a new model, look into $fillable.
This is my first deployment of FuelPHP, though I am a long time user of CodeIgniter.
I am getting the following error when I load the page:
ErrorException [ Fatal Error ]:
Class 'Model\Model_UPS' not found
/classes/controller/ups.php
<?php
use \Model\Model_UPS;
class Controller_UPS extends Controller {
public function action_index() {
$view = View::forge('json');
$view->title = Model_UPS::get_load();
return $view;
}
}
?>
/classes/model/model_ups.php or ups.php
<?php
namespace Model;
class Model_UPS extends \Model {
public static function get_load() {
return "This is the load!";
}
}
?>
/views/json.php
<?=$title;?>
The error page highlights the $view->title = Model_UPS::get_load(); line of ups.php. I have tried just about every configuration of use, namespace, model filename, and model class name that I can think of. I can't seem to find a super simple MVC example to use as a guide. I've tried to duplicate the FuelPHP Docs as best as I can, but have failed. Can anyone find anything wrong with this?
Rename file: model/model_ups.php to model/ups.php
Rename class: Model_UPS to UPS
Change: use \Model\Model_UPS; to use \Model\UPS;
Change: Model_UPS::get_load(); to UPS::get_load();
I was trying out Gas ORM, and have managed to auto-generate my models and now need to test them. However, I cannot seem to access the newly generated model.
I have the library autoloaded, and the config set up as:
config/gas.php
$config['models_path'] = array('GasModel' => APPPATH.'gas');
gas/useraccounts.php
<?php namespace GasModel;
/* This basic model has been auto-generated by the Gas ORM */
use \Gas\Core;
use \Gas\ORM;
class UserAccounts extends ORM {
public $primary_key = 'id';
function _init()
{
self::$fields = array(
'id' => ORM::field('auto[11]'),
...
);
}
}
controller/user.php
public function test() {
GasModel\UserAccounts::all()
}
Trying to access it however throws a fatal error:
PHP Fatal error: Class 'GasModel\UserAccounts' not found in applications/controllers/user.php on line 28
Can anyone help me in solving this issue?
Try add use of your model namespace or try add \ before GasModel
When I used back the same namespace as the example in http://gasorm-doc.taufanaditya.com/configuration.html, which is Model, it started working mysteriously. I would have preferred to use my custom namespace though..