this is my full code that I write it to test function from controller
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;
class RouteForecastTest extends TestCase
{
protected $password = 'rightpassword';
public function setUp()
{
parent::setUp();
$this->createApplication();
$this->user = factory(App\User::class)->create([
'email' => 'testuser#email.com',
'password' => bcrypt($this->password),
'type' => 'admin'
]);
}
/** #test */
public function createTest()
{
$this->actingAs($user);
$this->visit('/client/ocp/profile/247')
->click('New ')
->seePageIs('/client/ocp/profile/247/create')
->see('name');
}
public function tearDown(){
parent::tearDown();
$this->user->delete();
}
}
i try this code with setup and teardown methods and run test using phpunit i got this error
ErrorException: Undefined variable: user
how can I fix this error?
Related
Here is a custom exception
namespace App\Exceptions;
use Exception;
class CustomException extends Exception
{
public function render($request)
{
return response()->view('custom-exception');
}
}
I throw it inside a Request class
class LoginRequest extends FormRequest
{
public function authenticate()
{
if (! Auth::attempt($this->only('email', 'password'))) {
throw CustomException(); //
}
}
}
This is the controller which call the LoginRequest class
class AuthenticatedSessionController extends Controller
{
public function store(LoginRequest $request) //
{
$request->authenticateMember();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::Home);
}
}
This is the test
use Tests\TestCase;
use App\Models\User;
use App\Exceptions\CustomException;
class EmailVerificationTest extends TestCase
{
public function test_email_verification_screen_can_be_rendered()
{
$user = User::factory()->create([
'email_verified_at' => null,
]);
// $this->expectException(CustomException::class); //this cannot pass
$response = $this->post(
'/login',
[
'email' => 'john#example.com',
'password' => 'secret'
]
);
$response->assertViewIs('custom-exception');
$this->assertInstanceOf(CustomException::class, $response->exception);
}
}
These assertions can pass:
$response->assertViewIs('custom-exception');
$this->assertInstanceOf(CustomException::class, $response->exception);
But this one cannot pass:
$this->expectException(CustomException::class);
Failed asserting that exception of type "App\Exceptions\CustomException" is thrown.
Why? Any idea?
The method expectException() will only work when the exception thrown is not handled.
Please add the below line in your function
$this->withoutExceptionHandling();
then this method expectException() will work.
I want to mock a custom Validation rule (e.g. App\Rules\SomeRule). But when I run my test, it gives an Mockery\Exception\InvalidCountException: Method...should be called
exactly 1 times but called 0 times.
I've read Laravel's documentation on Mocking, on custom Validation Rules, Service Containers, Service Providers and I cannot figure out why I'm not successfully mocking the rule.
I read this thread but I'm struggling to connect it with my problem which is, "How can I test that my app is using this Rule". Or is that something I cannot test?
Here's my Rule
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class SomeRule implements Rule
{
public function passes($attribute, $value)
{
// some logic, returns TRUE if valid.
}
public function message()
{
//
}
}
My controller
namespace App\Http\Controllers;
use App\Rules\SomeRule;
use Illuminate\Http\Request;
class LoanController extends Controller
{
public function store(Request $request)
{
$request->validate([
'email' => ['required', new SomeRule]
]);
// ...insert in database, return json.
}
}
My Test
namespace Tests\Feature;
use Mockery;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\Rules\SomeRule;
class LoansTest extends TestCase
{
use RefreshDatabase;
public function tearDown(): void
{
parent::tearDown();
Mockery::close();
}
/** #test */
public function the_sad_path__when_email_is_invalid()
{
$rule = Mockery::mock(SomeRule::class)->shouldReceive('passes')->once();
$this->app->instance(SomeRule::class, $rule);
$response = $this->json('POST', '/api/loans', ['email' => 'whatevs#gmail.com']);
}
}
I played with the idea of registering SomeRule in the AppServiceProvider. But that still didn't do anything:
public function register()
{
$this->app->bind(SomeRule::class, function ($app) {
return new SomeRule();
});
}
Code in Github
you need to use like this
class LoanController extends Controller
{
public function store(Request $request)
{
$request->validate([
'email' => ['required', new SomeRule()]
]);
// ...insert in database, return json.
}
}
hello am new to phpunit test and am stuck here.
I've followed this tutorial: Zend Framework 2 : Centralize phpunit test
After that i created a module test
namespace ModulesTests\ServiceProvidersTest\Model;
use PHPUnit_Framework_TestCase;
use ModulesTests\ServiceManagerGrabber;
use User\Service\ServiceProvider;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
class TestServiceProviders extends PHPUnit_Framework_TestCase
{
protected $serviceManager;
protected $serviceprovider;
public function setUp()
{
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = new ServiceProvider() ;
}
public function testSPdetails()
{
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
}
}
In my ServiceProvider class
namespace User\Service;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorAwareTrait;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\Adapter\Adapter;
use Zend\Db\Sql\Sql;
class ServiceProvider implements ServiceLocatorAwareInterface
{
use ServiceLocatorAwareTrait;
public function getModel()
{
$em = $this->getServiceLocator()- >get('doctrine.entitymanager.orm_default');
return $em->getRepository('User\Entity\ServiceProvider');
}
public function getDetails($data = null,$fields='*')
{
$where = 1;
$company_ids = implode(',',$data);
if(isset($company_ids)){
$where = 'sp.id IN('.$company_ids.')';
}
if(isset($fields)){
}
$db = $this->getServiceLocator()->get('Zend\Db\Adapter\Adapter');
$query = 'some query';
.....Rest code.......
}
}
}
am getting this error :
Call to a member function get() on null in /opt/lampp/htdocs/project/module/User/src/User/Service/ServiceProvider.php
Please help what am missing here..??
So there are a few things I notice here:
1: You have not shown any code showing how you have hooked up your service to the service manager, so it is unclear if this will ever work
2: You directly instantiate your class when you need to be using the service manager grabber you have written
$this->serviceprovider = new ServiceProvider() ;
becomes
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = $this->serviceManager->get('YOUR_SERVICE_KEY');
3: You probably should start with unit tests not these module integration tests being explained in that article. see https://framework.zend.com/manual/2.3/en/modules/zend.test.phpunit.html
4: The ServiceLocatorAwareInterface is deprecated you should probably use a factory and the factories key of service manager config to inject your dependencies
5: Your code seems to mix doctrine and zend db I don't know why you've done this, but my suggestion is ... it's be a bad idea
Here is an example of how you might put this together:
module.config.php
<?php
namespace Application;
return [
'service_manager' => [
'factories' => [
'ServiceProvider' => function ($serviceManager) {
// This shouldn't be in this anon function, it should be its own
// factory but I'm lazy and already writing loads of code for this example
// #see https://framework.zend.com/manual/2.4/en/in-depth-guide/services-and-servicemanager.html#writing-a-factory-class
$service = new \Application\Service\ServiceProvider(
$serviceManager->get('doctrine.entitymanager.orm_default')
);
return $service;
},
]
],
];
ServiceProvider.php
<?php
namespace Application\Service;
use Doctrine\ORM\EntityManager;
class ServiceProvider
{
protected $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function getModel()
{
return $this->entityManager- >getRepository('User\Entity\ServiceProvider');
}
public function getDetails($data = null, $fields='*')
{
$serviceProviderRepository = $this->entityManager->getRepository('User\Entity\ServiceProvider');
return $data;
}
}
ModuleTest
<?php
namespace ModulesTests\Application\Service;
use PHPUnit_Framework_TestCase;
use ModulesTests\ServiceManagerGrabber;
class ServiceProvidersTest extends PHPUnit_Framework_TestCase
{
protected $serviceManager;
protected $serviceprovider;
public function setUp()
{
$serviceManagerGrabber = new ServiceManagerGrabber();
$this->serviceManager = $serviceManagerGrabber->getServiceManager();
$this->serviceprovider = $this->serviceManager->get('ServiceProvider');
}
public function testSPdetails()
{
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
}
}
unit test:
<?php
namespace ModulesTests\Application\Service;
use PHPUnit_Framework_TestCase;
use Application\Service\ServiceProvider;
use Prophecy\Argument;
class ServiceProvidersUnitTest extends PHPUnit_Framework_TestCase
{
protected $entityManager;
protected $serviceprovider;
public function setUp()
{
$this->entityManager = $this->prophesize("Doctrine\\ORM\\EntityManager");
$this->entityManager->getRepository(Argument::exact('User\Entity\ServiceProvider'))
->willReturn(true);
$this->serviceprovider = new ServiceProvider($this->entityManager->reveal());
}
public function testSPdetails()
{
$stack = array('1','2');
$this->serviceprovider->getDetails($stack);
$this->entityManager->getRepository(Argument::exact('User\Entity\ServiceProvider'))
->shouldHaveBeenCalledTimes(1);
}
}
I am about $this->close() to giving up on Mockery in my unit tests. Here's what's going on, I am working with Laravel 5.1 and I'm trying to test my repository pattern abstraction using Mockery in PHPUnit. I've followed the tutorials, poured over the StackOverflow questions so it's not a duplicate. When you see anything about modules here, it's PingPong Sky Modules package.
Basically, when I try to mock the repository interface and set shouldReceive('create')->with([])->once() , Mockery throws:
Mockery\Exception\InvalidCountException: Method create(array()) from Mockery_0_Modules_Documents_Repositories_DocumentRepositoryInterface should be called exactly 1 times but called 0 times.
DocumentsTest.php
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
class FileUploadTest extends TestCase {
use WithoutMiddleware;
public function mock($class){
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
public function testFileUpload(){
// Mock the Repository
$mock = $this->mock('\Modules\Documents\Repositories\DocumentRepositoryInterface');
$mock->shouldReceive('create')->with([])->once();
$this->call('POST', '/documents', [], [], []);
$this->assertResponseStatus(201);
}
}
DocumentRepositoryInterface.php
<?php namespace Modules\Documents\Repositories;
interface DocumentRepositoryInterface {
public function create(array $data);
}
DatabaseDocumentRepository.php
<?php namespace Modules\Documents\Repositories;
use Modules\Documents\Repositories\DocumentRepositoryInterface;
use \Illuminate\Database\Eloquent\Model;
class DatabaseDocumentRepository implements DocumentRepositoryInterface {
protected $documents;
public function __construct(Model $documents) {
$this->documents = $documents;
}
public function create(array $data) {
// Eloquent code.
return "response";
}
}
Document.php
<?php namespace Modules\Documents\Entities;
use Illuminate\Database\Eloquent\Model;
class Document extends Model {
protected $fillable = [];
}
routes.php
$this->app->bind(
'Modules\Documents\Repositories\DocumentRepositoryInterface', function(){
return new Modules\Documents\Repositories\DatabaseDocumentRepository(new Modules\Documents\Entities\Document());
});
Route::group(['prefix' => 'documents', 'namespace' => 'Modules\Documents\Http\Controllers'], function(){
Route::post('/', ['as' => '/', 'uses'=> 'DocumentsController#create']);
});
DocumentsController.php
<?php namespace Modules\Documents\Http\Controllers;
use Modules\Documents\Repositories\DocumentRepositoryInterface;
use Pingpong\Modules\Routing\Controller;
use Module;
use Illuminate\Http\Response;
use Illuminate\Http\Request;
class DocumentsController extends Controller {
private $documents;
public function __construct(DocumentRepositoryInterface $doc){
$this->documents = $doc;
}
public function create(Request $request){
$this->documents->create([]);
return response("", Response::HTTP_CREATED);
}
}
I want to say it has something to do with the mocked object not getting injected into the DocumentsController because the create() function is getting called. I put a print_r in the create function and it displayed in my console. This is strange and it could also be related to PingPong Sky Modules. What am I doing wrong or not doing?
I am trying to create a simple service in zf2 which I can access using in viewhelper
Step1. I have craeted a class in src/Application/Service/Service1.php as follow
namespace Application\Service;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
class Service1 implements ServiceLocatorAwareInterface
{
public function __construct()
{
}
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
}
public function getServiceLocator()
{
}
}
Step2 I set this up in module.php file as below.
public function getServiceConfig()
{
return array(
'factories' => array(
'Application\Service\Service1' => function ($sm) {
return new \Application\Service\Service1($sm);
},
)
);
}
public function onBootstrap($e)
{
$serviceManager = $e->getApplication()->getServiceManager();
$serviceManager->get('viewhelpermanager')->setFactory('Abc', function ($sm) use ($e) {
return new \Application\View\Helper\Abc($sm);
});
}
Step3 finally I am geting it in my view helper src/Application/View/Helper/Abc.php test() method like this, I I comment this line $this->sm->get('Application\Service\Service1'); there is no error, there must be something which I am missing in service?
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class Abc extends AbstractHelper
{
protected $sm;
public function test()
{
$this->sm->get('Application\Service\Service1');
}
public function __construct($sm) {
$this->sm = $sm;
}
}
Step4 then I am calling my test view helper in one of view like this.
$this->Abc()->test();
I am getting following error.
Fatal error: Call to undefined method Application\Service\Service1::setView() in vendor/zendframework/zendframework/library/Zend/View/HelperPluginManager.php on line 127 Call Stack:
what am I missing?
An alternative, in PHP 5.4 only, without specific configuration, would be to use traits:
extract of module.config.php:
'view_helpers' => array(
'invokables' => array(
'myHelper' => 'Application\View\Helper\MyHelper',
),
MyHelper.php:
<?php
namespace Application\View\Helper;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
class HeadScript extends \Zend\View\Helper\MyHelper implements ServiceLocatorAwareInterface
{
use \Zend\ServiceManager\ServiceLocatorAwareTrait;
public function __invoke()
{
$config = $this->getServiceLocator()->getServiceLocator()->get('Config');
// do something with retrived config
}
}
change the line $this->sm->getServiceLocator()->get('Application\Service\Service1'); in below method
class Abc extends AbstractHelper
{
protected $sm;
public function test()
{
$this->sm->getServiceLocator()->get('Application\Service\Service1');
}
public function __construct($sm) {
$this->sm = $sm;
}
}