I am new to PHP Mockery Framework. I have a mock function executePrepared($arg1, $arg2, arg3) which I am calling it twice but seems to be not working and gives below error in PHPUnit command line:
Configuration read from C:\xampp\htdocs\DatabaseTesting\phpunit.xml
..←[31;1mE←[0m
Time: 47 ms, Memory: 3.25Mb
There was 1 error:
1) Test\Database\Table\TableTest::testinsertMany
Mockery\Exception\NoMatchingExpectationException: No matching handler found for
Mockery_0_Database_PGC::executePrepared(array(0=>'ClayPipe',1=>2000,2=>2100,3=>1
,4=>'2000-01-01',5=>'{"1":"1","2":6,"3":8,"4":10}',), "insert_assets", "\Databas
e\Model\Asset"). Either the method was unexpected or its arguments matched no ex
pected argument list for this method
my test function is as below:
public function testinsertMany() {
$this->PGCMock->shouldReceive('executePrepared')->twice()->withArgs(array(
[array('Clay Pipe',2000,2100,1,'2000-01-01','{"1":"1","2":6,"3":8,"4":10}'), 'insert_assets', '\Database\Model\Asset'],
[array('Main Street',1000,1100,0,'2000-02-01','{"1":"1","2":6,"3":8,"4":10}'), 'insert_assets', '\Database\Model\Asset']))
->andReturn($expectedResult1);
$data1 = array('name'=>'Clay Pipe',
'hist_cost' => 2000,
'val_cost' => 2100,
'val_method' => 1,
'service_date' => '2000-01-01',
'tags' => '{"1":"1","2":6,"3":8,"4":10}'
);
$data2 = array('name'=>'Main Street',
'hist_cost' => 1000,
'val_cost' => 1100,
'val_method' => 0,
'service_date' => '2000-02-01',
'tags' => '{"1":"1","2":6,"3":8,"4":10}'
);
$actualResult = $this->tableMock->insertMany(array($data1,$data2));
}
I don't understand what's wrong here. Is my Syntax for calling mock function twice() with passed argument wrong? Could any body please guide me here?
twice() should be used when the same call (including arguments) is expected to be executed 2 times. Looks like you want to check 2 consecutive calls, each with distinct argument.
If that is the case, this would work:
$this->PGCMock
->shouldReceive('executePrepared')
->once()
->ordered()
->withArgs([
array('Clay Pipe',2000,2100,1,'2000-01-01','{"1":"1","2":6,"3":8,"4":10}'),
'insert_assets', '\Database\Model\Asset'
])
->andReturn($result1);
$this->PGCMock
->shouldReceive('executePrepared')
->once()
->ordered()
->withArgs([
array('Main Street',1000,1100,0,'2000-02-01','{"1":"1","2":6,"3":8,"4":10}'),
'insert_assets', '\Database\Model\Asset'
])
->andReturn($result2);
Related
In Laravel I have programmed a console command to do a database operation. The command should take two parameters: <single> and <plural>. The console command should look like: $ php artisan entities:make pagespeed_sample pagespeed_samples. This short program resides in a vendor package, installed by composer: https://packagist.org/packages/phitech/entities. When I tested it while it was still in the /routes/console.php of my laravel application, it worked correctly. But now after installing it as a package, it doesn't work. I do not know by the way whether I have perhaps changed anything inbetween to break it.
The program returns an error: "No arguments expected for "entities:make" command, got "pagespeed_sample".".
Why does it say it is not expecting any arguments? Also, when I try it without arguments, it returns the error: "Unable to resolve dependency [Parameter #0 [ $single ]] in class Illuminate\Foundation\Console\ClosureCommand".
Is there a way to explicitly define expected arguments for my command, besides having the arguments required in the callback?
The full code of this console command is found below. I am using Laravel Framework 9.35.1.
Artisan::command('entities:make', function ($single, $plural) {
$entity_definition = json_encode([
"entity_name" => $single,
"main_db_table" => $plural,
"meta_db_table" => $plural . "_meta",
"meta_instance_id" => $single . "_id",
"main_required_columns" => [$single . "_id"],
]);
DB::table('entities')->insert([
'name' => $single,
'definition' => $entity_definition
]);
})->purpose('Register a new entity definition.');
Closure command parameters need to be part of the command definition e.g.
Artisan::command('entities:make {single} {plural}', function ($single, $plural) {
$entity_definition = json_encode([
"entity_name" => $single,
"main_db_table" => $plural,
"meta_db_table" => $plural . "_meta",
"meta_instance_id" => $single . "_id",
"main_required_columns" => [$single . "_id"],
]);
DB::table('entities')->insert([
'name' => $single,
'definition' => $entity_definition
]);
})->purpose('Register a new entity definition.');
I create a factory of a model inside an artisan command:
public function handle()
{
if (!$this->isDevelopment()) {
$this->errorMessageSwitchEnvToDev();
return;
}
$userId = $this->ask('Please specifiy user_id you want to add the payouts to.',2148);
$numberOfPayouts = $this->ask('How many payouts you want to generate?', 10);
factory(\App\Payout::class, $numberOfPayouts)->create([
'user_id' => $userId,
]);
}
The artisan works on my local desktop, but it does not work after deployment on my test server.
I get the following error message:
InvalidArgumentException : Unable to locate factory with name [100] [App\Payout].
at /www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:269
265| */
266| protected function getRawAttributes(array $attributes = [])
267| {
268| if (! isset($this->definitions[$this->class][$this->name])) {
> 269| throw new InvalidArgumentException("Unable to locate factory with name [{$this->name}] [{$this->class}].");
270| }
271|
272| $definition = call_user_func(
273| $this->definitions[$this->class][$this->name],
Exception trace:
1 Illuminate\Database\Eloquent\FactoryBuilder::getRawAttributes([])
/www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:292
2 Illuminate\Database\Eloquent\FactoryBuilder::Illuminate\Database\Eloquent\{closure}()
/www/htdocs/w0146a6f/dev/dev4.partner.healyworld.net/releases/20201014150056/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php:122
I do the deployment with envoyer.
My factory is defined in database/factories/PayoutFactory.php
<?php
$factory->define(\App\Payout::class, function (Faker\Generator $faker) {
return [
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'amount' => $faker->randomFloat(2),
'req_amount' => 0,
'tax_amount' => 0,
'withheld' => 0,
'vat_rate' => $faker->randomNumber(2),
'released_amount' => $faker->randomFloat(2),
'released_amount_local_currency' => $faker->randomFloat(2),
'status' => 'released',
'flag' => 0,
'created_at' => $faker->dateTimeBetween('-6 months', 'now'),
];
});
However, it won't work on production. I already cleared the cache, the routes and called composer dump-autoload, but it still failes with the same issue.
Any suggestions?
I also read all answers of Laravel 5.2: Unable to locate factory with name [default] but none of them worked.
Notice this:
Unable to locate factory with name [100]
It looks like factory() is willing to use states instead of quantity. In this case it's looking for a factory state called (string) "100" instead of (int) 100
Cast your amount variable to be an integer
$numberOfPayouts = (int) $this->ask('How many payouts you want to generate?', 10);
Alternatively, try using ->times($amount) method to be more explicit.
This question already has answers here:
Is it possible to define a class property value dynamically in PHP?
(2 answers)
Closed 7 years ago.
PHP version 5.6. Code:
protected $siteServices = [
1 => [
'title' => 'Consulting',
'key' => 'service',
'description' => '',
'file' => asset('assets/img/sample/image1.jpg'), // throws error on this line
],
];
Error: PHP Parse error: syntax error, unexpected '(', expecting ']'
What would be a possible fix for this?
Edit
Solved by moving the variable in the running function instead of making it protected. Also can be solved by declaring the empty variable first then set the values in __constructor()
It could be done but it in a different way. I have listed two different methods.
First method
protected $siteServices = [
1 => [
'title' => 'Consulting',
'key' => 'service',
'description' => '',
'file' => ['asset', 'assets/img/sample/image1.jpg'] // throws error on this line
]
];
I replaced the function call with an array assigned to the file key in this array. So, now, you'd be wondering how you could call the asset function, yeah? It is pretty simple.
While you are looping through that array, you can do this:
call_user_func($siteServices[1]['file'][0], $siteServices[1]['file'][1]);
So, what are we doing here?
Firstly, we set an array to the file key where the first element of the array is the name of the function, while the other element is the value for the parameter that needs to be passed to the function defined previously.
So, using the PHP's call_user_func function, you can call functions giving their name and the parameters. I hope this helps you out.
Second method
I am pretty sure you will have a setter function for this property. Therefore, you could do something like this:
public function setSiteService($title, $key, $description, $file)
{
$file = asset($file);
$service = [
'title' => $title,
'key' => $key,
'description' => $description,
'file' => $file
];
$this->siteServices[] = $service;
}
So, the setter does the processing part for you. Hardcoding arrays is not at all a good idea, you should definitely populate through some mechanism.
Lately I've been having problems with PHPUnit, which keeps complaining about missing PHPUnit_Extensions_Story_TestCase despite the fact that the extension is installed (previous installed using pear install phpunit/PHPUnit_Story).
This only happens when I'm running a unit test that fails. So, instead of having a "normal" proper failure stack trace, I have something like this:
ECould not find PHPUnit_Extensions_Story_TestCase
#0 PHPUnit_Util_Fileloader::{closure}(PHPUnit_Extensions_Story_TestCase) called at [/Users/pedro/Code/Repositories/api-v2/src/XXX/system/Autoloader.php:40]
#1 Autoloader->autoload(PHPUnit_Extensions_Story_TestCase)
#2 spl_autoload_call(PHPUnit_Extensions_Story_TestCase)
#3 class_exists(PHPUnit_Extensions_Story_TestCase) called at [phar:///usr/bin/phpunit/phpunit/Util/Blacklist.php:110]
#4 PHPUnit_Util_Blacklist->initialize() called at [phar:///usr/bin/phpunit/phpunit/Util/Blacklist.php:74]
#5 PHPUnit_Util_Blacklist->isBlacklisted(phar:///usr/bin/phpunit/php-invoker/Invoker.php) called at [phar:///usr/bin/phpunit/phpunit/Util/Filter.php:105]
#6 PHPUnit_Util_Filter::getFilteredStacktrace(PHP_Invoker_TimeoutException Object ([] => Execution aborted after 5 seconds,[] => ,[] => 0,[] => phar:///usr/bin/phpunit/php-invoker/Invoker.php,[] => 111,[] => Array ([0] => Array ([file] => /Users/pedro/Code/Repositories/api-v2/src/XXX/data/adapters/MySQLiAdapter.php,[line] => 160,[function] => callback,[class] => PHP_Invoker,[type] => ->,[args] => Array ([0] => 14)),[1] => Array ([file] => /Users/pedro/Code/Repositories/api-v2/src/XXX/data/adapters/MySQLiAdapter.php,[line] => 306,[function] => query,[class] => XXX\data\adapters\MySQLiAdapter,[type] => ->,[args] => Array ([0] => SELECT * FROM `users` ORDER BY RAND() LIMIT 82 )),[2] => Array ([file] => /Users/pedro/Code/Repositories/api-v2/src/XXX/data/objects/Mapper.php,[line] => 138,[function] => select,[class] => XXX\data\adapters\MySQLiAdapter,[type] => ->,[args] => Array ([0] => `users`,[1] => ,[2] => RAND(),[3] => 82)),[3] => Array ([file] => /Users/pedro/Code/Repositories/api-v2/src/XXX/resources/hybrid/Users.php,[line] => 53,[function] => read,[class] => XXX\data\objects\Mapper,[type] => ->,[args] => Array ([0] => RAND(),[1] => 82)),[4] => Array ([function] => read,[class] => XXX\resources\hybrid\Users,[type] => ->,[args] => Array ([0] => XXX\data\objects\Operation Object
This goes on how don't know how many hundreds of lines more until if finally tells the actual problem:
Time: 20.35 seconds, Memory: 18.50Mb
There was 1 failure:
1) Tests\XXX\resources\hybrid\NotificationsTest::testReadNotificationsWithLimit
Failed asserting that '4567135422196220076' matches expected 4567135456555958453.
/Users/pedro/Code/Repositories/api-v2/tests/XXX/resources/hybrid/NotificationsTest.php:168
FAILURES!
Tests: 5, Assertions: 15, Failures: 1.
Generating code coverage report in Clover XML format ...
I'm running PHPUnit 4.0.10 and have installed PHPUnit_Story-1.0.2 . I understand that this is not a normal behaviour, but unfortunately I don't know how to get rid of this. Any suggestions?
P.S. - I was checking /usr/bin/phpunit file and in the autoload function, the $classes array is missing an entry with 'phpunit_extensions_story_testcase' ...but if I try to edit the file, Phar complains about invalid signature.
Your custom autoloader at /Users/pedro/Code/Repositories/api-v2/src/XXX/system/Autoloader.php is outputting that stuff instead of returning false on line 40. Without seeing the source code of said autoloader, it's impossible to say why that is happening.
PHP autoloaders are supposed to silently return false if a class cannot be loaded. This is required to allow chaining multiple autoloaders. PHPUnit uses its own autoloader for its own code which cannot run correctly due to your custom autoloader not following the spec.
I have the same problem and the only way I solved it --for now-- was downgrading to PHPUnit 3.7.32.
Had the same problem with phpunit 4.x. in combination with the Yii 1.x autoloader. Unit testing works fine, usually, but breaks as soon as I enable code coverage.
Disclaimer: The following is really ugly but it works for me:
Just add an empty class to your project so the autoloader doesn't fail.
<?php
if(!class_exists('PHPUnit_Extensions_Story_TestCase'))
{
/**
* PHPUnit_Extensions_Story_TestCase
*
* This skeleton class is added to get code coverage collection using XDebug
* and PHPUnit 4.x working again.
*/
class PHPUnit_Extensions_Story_TestCase
{
}
}
Using the latest CakePHP build 1.3.6.
I'm writing a custom datasource for a external REST API. I've got all the read functionality working beautifully. I'm struggling with the Model::save & Model::create.
According to the documentation, the below methods must be implemented (see below and notice it does not mention calculate). These are all implemented. However, I was getting an "Fatal error: Call to undefined method ApiSource::calculate()". So I implemented the ApiSource::calculate() method.
describe($model) listSources() At
least one of:
create($model, $fields = array(), $values = array())
read($model, $queryData = array())
update($model, $fields = array(), $values = array())
delete($model, $id
= null)
public function calculate(&$model, $func, $params = array())
{
pr($model->data); // POST data
pr($func); // count
pr($params); // empty
return '__'.$func; // returning __count;
}
If make a call from my model
$this->save($this->data)
It is calling calculate, but none of the other implemented methods. I would expect it to either call ApiSource::create() or ApiSource::update()
Any thoughts or suggustions?
Leo, you tipped me in the right direction. The answer was in the model that was using the custom datasource. That model MUST define your _schema.
class User extends AppModel
{
public $name = 'User';
public $useDbConfig = 'cvs';
public $useTable = false;
public $_schema = array(
'firstName' => array(
'type' => 'string',
'length' => 30
),
'lastName' => array(
'type' => 'string',
'length' => 30
),
'email' => array(
'type' => 'string',
'length' => 50
),
'password' => array(
'type' => 'string',
'length' => 20
)
);
...
}
I'm guessing that if you implement a describe() method in the custom datasource that will solve the problem too. In this case it needed to be predefined to authorize the saves and/or creation.
From the API: http://api13.cakephp.org/class/dbo-source#method-DboSourcecalculate
"Returns an SQL calculation, i.e. COUNT() or MAX()"
A quick search in ~/cake finds 20 matches in 8 files. One of those is the definition in dbo_source.php
The other seven are:
dbo_source.test.php
code_coverage_manager.test.php
code_coverage_manager.php
dbo_db2.php
model.php
tree.php
containable.php
Without delving too deeply into this, I suspect your problem lies in Model::save
You'll probably have to define a calculate method to suit the structure of your custom datasource because Cake won't know how to do that.