Session class not available in setUpBeforeClass - laravel-4

When my very first unit test class is run, why is the Session class not available in setUpBeforeClass? After the first unit test class has finished, the session class is available in setUpBeforeClass.
Is there something I can do to make sure that Session is available in my first unit test?
<?php
class AATest extends TestCase
{
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
\Session::put('tenantId',100); // <-- this fails
\Session::put('userId',1100);
}
public function setUp()
{
parent::setUp();
\Session::put('tenantId',100); // <-- if removed from before class, this works.
\Session::put('userId',1100);
}
public function test1()
{
$tenantId = \Session::get('tenantId');
$userId = \Session::get('userId');
$this->assertEquals(100,$tenantId);
$this->assertEquals(1100,$userId);
}
}

Related

Laravel contextual binding to be more specific to methods rather then class only

I am trying to understand laravel bind.
let's say, I have UploadFileController.php
Route::post('/upload/images', 'UploadFilesController#uploadImage');
Route::post('/upload/pdf', 'UploadFilesController#uploadPdf');
then in the controller,
class UploadFilesController extends Controller
{
private $uploadServiceInterface;
public function __construct(UploadServiceInterface $uploadServiceInterface)
{
$this->uploadServiceInterface = $uploadServiceInterface;
}
public function uploadImage(Request $request)
{
$this->uploadServiceInterface->store();
}
public function uploadPdf()
{
$this->uploadServiceInterface->store();
}
}
Now, the uploadServiceProvider,
class UploadServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->when(UploadFilesController::class)
->needs(UploadServiceInterface::class)
->give(ImagesUploadService::class);
}
}
Now, I know "when" says that UploadFileController class with uploadService interface will give the imageUploadService but is it possible I make it more specific to function in uploadFileController class, like
$this->app->when(uploadFilesController::uploadImage())
->needs(UploadServiceInterface::class)
->give(ImagesUploadService::class);
then it takes to the imagesUploadService class same for pdf upload class.

How to mock classes within command classes in Laravel

I am using Laravel 5.3. For a procedur I am using a command. The command class is calling a method of an another class. I wanted to unit test it with phpunit. Therefore I mocked up the class within the command class. When I run the test, then the actual method of class is running and not the mocked method. Bevor I have implemented the functinality of the command in a job. There I can call the mocked method without any problem.
The test class looks like this:
class CommandTest extends TestCase
{
public function setUp()
{
parent::setUp();
$this->api = $this->getMockBuilder('App\Services\APIRepository')
->setMethods(['getStatus'])
->getMock();
}
/** #test */
public function test_api()
{
...
$this->api->expects($this->any())
->method('getStatus')
->will($this->returnValue($api_response));
\Artisan::call('myapp:tracker',[]);
...
}
}
class Command extends Command
{
protected $signature = 'myapp:tracker';
private $api;
public function __construct(APIRepository $api)
{
$this->api = $api;
}
public function handle()
{
...
$status = $this->api->getStatus(...);
var_dump($status);
...
}
}
The output of var_dump($status) is: NULL
Do I need a special method for mocking a class within a command class?
Thanks a lot in advanced!

How to reuse PHPUnit functions

I want to reuse some of my PHPUnit functions by calling them instead of repeating them in all unit tests, such as this for example:
public function testContent()
{
$this->assertNotEmpty($this->response, $this->message);
}
If I place it under tests/TestCase.php, it runs for all the unit tests.
Where would be the right place to put this or how is this usually done? Btw, I am using it on Laravel 4.
Apparently, your problem is not to re-use tests, but that your tests are beeing called when it's not expected.
So, have in your mind: any method with a name starting with "test" (testFoo, testBar) in an existing class will be considered as a test.
So if you have classes A, B and C like this
class A extends \PHPUnit_Framework_TestCase {
public function testFoo() {...}
public function testBar() {...}
}
class B extends A {
public function testBaz() {...}
}
class C extends A {
public function testQuz() {...}
}
you will have 8 tests: A::testFoo(), A::testBar(), B::testFoo(), B::testBar(), B::testBaz(), C::testFoo(), C::testBar(), C::testQuz().
It's probably is not what you was trying to make.
You may want to have testFoo and testBar only in classes B and C, not it A. In this case, you just have to declare A as an abstract class.
abstract class A extends \PHPUnit_Framework_TestCase {
public function testFoo() {...}
public function testBar() {...}
}
class B extends A {
public function testBaz() {...}
}
class C extends A {
public function testQuz() {...}
}
Now you have 6 tests: B::testFoo(), B::testBar(), B::testBaz(), C::testFoo(), C::testBar(), C::testQuz().
Maybe, it's what you need, maybe not. Maybe, you want to have testFoo() and testBar() only in some inherited classes, not all of them.
In this case, make assertions in you parent class instead of tests.
abstract class A extends \PHPUnit_Framework_TestCase {
public function assertFoo() { ... }
public function assertBar() { ... }
}
class B extends A {
public function testFoo() { $this->assertFoo(); ...}
public function testBaz() {...}
}
class C extends A {
public function testBar() { $this->assertBar(); ...}
public function testQuz() {...}
}
Now, you have only 4 tests: B::testFoo(), B::testBaz, C::testBar(), C::testQuz()
Make your own assertion according to this manual
Make something like
namespace Vendor\Library\Tests;
abstract class BaseTestCase extends \PHPUnit_Framework_TestCase
{
public function assertContentNotEmpty($response) {
$this->assertNotEmpty($response);
}
}
And then extend this class with your tests.
If this approach is not convenient for some reasons, you can make an assertion as a separate class.

Laravel dependency injection into custom non-controller class fails in PHPUnit

all.
For a Laravel project I'm working on, I've started to use Dependency Injection in order to mock classes in my tests. However, I've found that if I try to inject into a custom class with no explicit parent, two things are true:
The dependency injection works correctly when running the application
The injection fails when running tests in PHPUnit
Here is some sample code similar to what I'm using:
DemoController
// The controller we're testing
class DemoController extends Controller
{
// The injection and constructor
private $helpLayer1;
public function __construct(HelpLayer1 $helpLayer1)
{
$this->helpLayer1 = $helpLayer1;
}
...
// The test function I call
public function testDeps()
{
$this->helpLayer1->testLayer1();
}
}
HelperLayer1
// Our first helper class
class HelperLayer1
{
private $helpLayer2;
public function __construct(HelpLayer2 $helpLayer2)
{
$this->helpLayer2 = $helpLayer2;
}
...
// The testing function
public function testLayer1()
{
// When called via route, this dumps the actual object
// When called via test, this returns null
dd($this->helperLayer2);
}
}
Helper1ServiceProvider
class Helper1ServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('HelperLayer1', function()
{
return new HelperLayer1(App::make('HelperLayer2'));
});
}
[OR]
public function register()
{
$this->app->bind('HelperLayer1', 'HelperLayer1');
}
}
Helper2ServiceProvider
class Helper2ServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind('HelperLayer2', 'HelperLayer2');
}
}
I'm relatively new to using DI, so I'm not entirely sure that this set-up is correct, but I'm at a loss.
Any help would be greatly appreciated! Thank you!

php class do once for all instances

So I have a class whose constructor downloads some xml and reads it into properties for the class to work with. I'm instantiating this class a couple of times and this time-consuming job is done three times in exactly the same manner. Could I avoid it somehow (I guess with a static method/properties)? My class should only once go get the properties and then every instance could use them. I feel I should put the code out of my constructor in a static function, but how it's done exactly, I don't know, since I always get errors.
class MyClass {
protected $xml_file;
protected $xml_derived_array;
public function __construct($param1, $param2, $param3) {
//get xml_file and make xml_derived_array with it
//do some other stuff with parameters and properties such as $xml_derived_array
}
}
Should become something like: (but how should I call the static properties in my __construct and how should I set the properties in the static function?)
class MyClass {
protected static $xml_file;
protected static $xml_derived_array;
protected static function get_xml() {
//get xml_file and make xml_derived_array with it (?how exactly?)
}
public function __construct($param1, $param2, $param3) {
self::get_xml();
//do some other stuff with parameters and properties such as $xml_derived_array (?how exactly?)
}
}
Edit
This is how it is now working:
class MyClass {
protected static $xml_file;
protected static $xml_derived_array = array();
public function __construct($param1, $param2, $param3) {
if (!self::$xml_file) {
self::$xml_file = simplexml_load_file('xml_file.xml');
self::$xml_derived_array[0] = self::$xml_file->title;
}
echo self::$xml_derived_array[0].$param1;
}
}
You don't need a static method. Just check if the property has a value in constructor and if not get the xml file and process it.
class MyClass {
protected static $xml_file;
protected static $xml_derived_array = array();
public function __construct($param1, $param2, $param3) {
if (! count(self::$xml_derived_array)){
//get xml_file and make xml_derived_array with it
//do some other stuff with parameters and properties such as $xml_derived_array
}
}
}

Resources