If I crate the class for test like:
class ReturnHandlerTest extends OrderKernelTestBase
{
protected static $modules = [
'commerce_payment',
'commerce_payment_example',
];
protected function setUp(): void {
parent::setUp();
}
}
And if I want to use
Url::fromRoute('commerce_payment.checkout.return', $arguments)
->setOptions(['absolute' => true])
->toString()
in my test case
In the test, I get this exception:
Symfony\Component\Routing\Exception\RouteNotFoundException: Route "commerce_payment.checkout.return" does not exist.
What should I do?
I should include the module "commerce_checkout".
protected static $modules = [
'commerce_payment',
'commerce_payment_example',
'commerce_checkout',
];
Related
I'm trying to test a class that handles a user's collection of favorite items, which can be of different types, eg. movies and songs.
So I have this base test class (I'm using Codeception, which uses Phpunit):
class BaseCollectionTest extends \Codeception\Test\Unit {
public function setUp() : void {
parent::setUp();
$this->userId = $this->tester->createUser();
$this->tester->login( $this->userId );
}
public function dataProvider() {
return [
[ new CollectionService( "movies", $this->userId ) ],
[ new CollectionService( "songs", $this->userId ) ]
];
}
}
Now I want to test whether a user can rename an existing collection, so I would like to create a collection first before the renaming tests are executed. IDEALLY, I could do this:
class RenameCollectionTest extends BaseCollectionTest {
protected $collection;
protected $Service;
/**
* #dataProvider dataProvider
*/
public function setUp( $Service ) : void {
parent::setUp();
$this->Service = $Service;
$this->collection = $this->Service->create_collection();
}
public function testRenamesCollection() {
$renamedCollection = $this->Service->rename_collection( $this->collection["id"], "New Title" );
$this->assertEquals( $renamedCollection["title"], "New Title" );
}
}
However, I've read that data providers can't be used with setUp. So I've tried a bunch of workarounds, most notably this:
class RenameCollectionTest extends BaseCollectionTest {
/**
* #dataProvider dataProvider
*/
public function testCreatesCollection( $Service ) {
$this->Service = $Service;
return $this->Service->create_collection();
}
/**
* #depends testCreatesCollection
*/
public function testRenamesCollection( array $collection ) {
$renamedCollection = $this->Service->rename_collection( $collection["id"], "New Title" );
$this->assertEquals( $renamedCollection["title"], "New Title" );
}
}
From what I've read, testRenamesCollection should receive the result of testCreatesCollection as its argument because of the #depends annotation, but I get a type error complaining that $collection received by testRenamesCollection is null and not an array (although I have verified that the return value of testCreatesCollection is in fact an array with the newly created collection data).
What other options do I have other than having to create a collection in each one of the renaming tests?
It seems you don't need you first test (which doesn't assert anything ?)
Indeed you can't put any logic in dataproviders, the easiest way for me should be:
public function dataProvider()
{
return [
[ "movies", $this->userId ],
[ "songs", $this->userId ]
];
}
/**
* #dataProvider dataProvider
*/
public function testCreatesAndRenamesCollection( $collectionName, $userId )
{
$this->Service = new CollectionService( $collectionName, $userId );
$collection = $this->Service->create_collection();
$renamedCollection = $this->Service->rename_collection( $collection["id"], "New Title" );
$this->assertEquals( $renamedCollection["title"], "New Title" );
}
(I would rather use simple properties in dataproviders to avoid duplicate code and have better maintanibility)
I am using model factories in NewsTableSeeder, but I get this error when I entered db:seed.
I want to know why I can't use create() in my seeder.
Here is my News model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class News extends Model
{
protected $table = 'news';
protected $primaryKey = 'id';
public function home_news_lists() {
return $this->select('id', 'news_title', 'news_update')
->orderBy('news_update', 'DESC')
->limit(5)
->get();
}
public function lists() {
return News::all();
}
}
Model Factories:
$factory->define(App\Models\News::class, function (Faker\Generator $faker)
{
static $password;
$faker = $faker->create('zh_TW');
return [
'news_title' => $faker->sentence(),
'news_content' => $faker->paragraph(),
'news_author' => $faker->name(),
'news_pageviews' => $faker->numberBetween(1, 100),
'news_file' => ' ',
'news_img' => $faker->imageUrl($width, $height, 'business'),
'created_at' => $faker->dateTimeBetween('2012', 'now', 'zh_TW'),
'updated_at' => $faker->dateTimeBetween('2015', 'now', 'zh_TW')
];
});
NewsTableSeeder :
<?php
use Illuminate\Database\Seeder;
class NewsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
factory(App\Models\News::class, 50)->create();
}
}
I can't tell 100% without seeing exactly the error you got, but I do believe there is no create() method on the $faker object.
I believe what you mean to do is:
$factory->define(App\Models\News::class, function (Faker\Generator $faker)
{
static $password;
$faker = \Faker\Factory::create('zh_TW'); // change to this
return [
...
];
}
I would just create a new faker generator (\Faker\Generator) that gets returned from calling \Faker\Factory::create($locale) and use that instead. Otherwise, I believe your next best option is to override wherever Laravel instantiates the \Faker\Generator $faker object that gets passed into the callback, but that may get hacky if Laravel doesn't provide a clean way to do it.
The create() method is a static call on the \Faker\Factory method. It accepts a locale as the parameter and uses en_US as the default locale.
$faker = $faker->create('zh_TW');
The error message said this code is wrong.
What is your purpose to use this code?
I am trying to extend an existing plugin component and I
need to add a function but use plugins methods.
Here what I have:
<?php namespace Bbrand\Shop\Components;
use Cms\Classes\ComponentBase;
use Jiri\JKShop\Components\Basket;
class Shopextend extends ComponentBase
{
public function componentDetails()
{
return [
'name' => 'shopextend Component',
'description' => 'No description provided yet...'
];
}
public function defineProperties()
{
return [];
}
public function onBasket(){
$data = [];
$data["basket"] = Basket::getSessionBasket();
$data["jkshopSetting"] = \Jiri\JKShop\Models\Settings::instance();
return [
$this->property("idElementWrapperBasketComponent") => $this->renderPartial('#basket-0', $data)
];
}
}
But I'm getting an error
"Non-static method Jiri\JKShop\Components\Basket::getSessionBasket()
should not be called statically" on line 30 of
/Applications/MAMP/htdocs/fidgycube.co/plugins/bbrand/shop/components/Shopextend.php
Any help!?
thanks
You need to add component first.
<?php namespace Bbrand\Shop\Components;
class Shopextend extends ComponentBase
{
public function init()
{
// Add component
$this->addComponent('\Jiri\JKShop\Components\Basket', 'basket', []);
}
}
I have a PHP class that has a constructor which takes arguments:
ex:
Users.php
namespace Forms;
class Users
{
protected $userName;
protected $userProperties = array();
public function __construct($userName, array $userProperties = null)
{
$this->userName = $userName;
$this->userProperties = $userProperties;
}
public function sayHello()
{
return 'Hello '.$this->userName;
}
}
Now, I am trying to use this class in a Model file like this:
$form = new Forms\Users( 'frmUserForm', array(
'method' => 'post',
'action' => '/dosomething',
'tableWidth' => '800px'
) );
It works just fine. However, in order to write Unit tests, I need to refactor this to a Service Factory, so I can mock it.
So, my Service factory now looks like this:
public function getServiceConfig()
{
return array(
'initializers' => array(
function ($instance, $sm)
{
if ( $instance instanceof ConfigAwareInterface )
{
$config = $sm->get( 'Config' );
$instance->setConfig( $config[ 'appsettings' ] );
}
}
),
'factories' => array(
'Forms\Users' => function ($sm )
{
$users = new \Forms\Users();
return $users;
},
)
);
}
With this refactoring in place, I have two questions:
How do I use the Forms\Users Service in the Model File, considering ServiceLocator is not available in a model file?
How can I change the Service Factory instance to take arguments for the constructor while instantiating Users class in the model.
I faced similar issue some time. Then I decide not to pass arguments to Factory itself. But build setter methods for handling this like.
namespace Forms;
class Users
{
protected $userName;
protected $userProperties = array();
public function setUserName($userName)
{
$this->userName = $userName;
}
public function setUserProperties($userProperties)
{
$this->userProperties = $userProperties;
}
public function sayHello()
{
return 'Hello '.$this->userName;
}
}
You can implement your model ServiceLocatorAwareInterface interface Then it would can call any service like below.
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class MyModel implements ServiceLocatorAwareInterface
{
protected $service_manager;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->service_manager = $serviceLocator;
}
public function getServiceLocator()
{
return $this->service_manager;
}
public function doTask($name, $properties)
{
$obj = $this->getServiceLocator('Forms\Users');
$obj->setUserName($name);
$obj->setUserProperties($properties);
}
}
I'm overriding the create() Eloquent method, but when I try to call it I get Cannot make static method Illuminate\\Database\\Eloquent\\Model::create() non static in class MyModel.
I call the create() method like this:
$f = new MyModel();
$f->create([
'post_type_id' => 1,
'to_user_id' => Input::get('toUser'),
'from_user_id' => 10,
'message' => Input::get('message')
]);
And in the MyModel class I have this:
public function create($data) {
if (!Namespace\Auth::isAuthed())
throw new Exception("You can not create a post as a guest.");
parent::create($data);
}
Why doesn't this work? What should I change to make it work?
As the error says: The method Illuminate\Database\Eloquent\Model::create() is static and cannot be overridden as non-static.
So implement it as
class MyModel extends Model
{
public static function create($data)
{
// ....
}
}
and call it by MyModel::create([...]);
You may also rethink if the auth-check-logic is really part of the Model or better moving it to the Controller or Routing part.
UPDATE
This approach does not work from version 5.4.* onwards, instead follow this answer.
public static function create(array $attributes = [])
{
$model = static::query()->create($attributes);
// ...
return $model;
}
Probably because you are overriding it and in the parent class it is defined as static.
Try adding the word static in your function definition:
public static function create($data)
{
if (!Namespace\Auth::isAuthed())
throw new Exception("You can not create a post as a guest.");
return parent::create($data);
}
Of course you will also need to invoke it in a static manner:
$f = MyModel::create([
'post_type_id' => 1,
'to_user_id' => Input::get('toUser'),
'from_user_id' => 10,
'message' => Input::get('message')
]);