How to call dispatchShell on same shell for another method? - shell

I have a cake shell, say DemoShell. And, from a method 'method1', I want to create another process which executes 'method2' of DemoShell. How can that be done?
class DemoShell extends AppShell {
// some code
private function method1() {
// some code
$success = $this->dispatchShell('Demo', 'method2', $params);
// some more code
}
private function method2() {
// some code to do something and return boolean value
}
}
I tried this, but method2 isn't getting called.

Related

Laravel mock multiple dependency

I have a Controller that has a dependency with BillingService, and BillingService has another dependency on UserService.
I need to call the Controller method getPlans and in this call I need to mock two functions:
loadPlans that is inside BillingService
getUsage that is in UserService
This is the full example:
class BillingPlanController
{
public function __construct(private BillingPlanService $billingPlanService)
{
}
public function getPlans()
{
$plans = $this->billingPlanService->getPlans();
//
}
}
class BillingPlanService
{
public function __construct(private UserService $userService)
{
}
public function getPlans()
{
$plans = $this->loadPlans();
$user = auth()->user();
$usage = $this->userService->getUsage(user); // DO SOMETHING, NEED TO MOCK .. HOW ?
}
public function loadPlans()
{
// DO SOMETHING, NEED TO MOCK .. HOW ?
}
}
At the end, in my test i simply call:
getJson(action([BillingPlanController::class, "getPlans"]));
In other tests, I'm able to mock a single Service, but in this scenario, I don't know how to write the mocks.
Sorry if I don't provide any "tries", but I really don't know how I can do that.
UPDATE
I tried to use partialMock and mock, but I get this error (when getUsage is called) - partialMock is used because i just need to mock a single function:
Typed property App\Modules\Billing\Services\BillingPlanService::$userService must not be accessed before initialization
$this->mock(UserService::class, function ($mock) {
$mock->shouldReceive("getUsage")->andReturn([]);
});
$this->partialMock(BillingPlanService::class, function ($mock) {
$mock->shouldReceive("loadPlans")->andReturn([]);
});
getJson(action([BillingPlanController::class, "getPlans"]));
Your exception in your partial mock, is because when you mock the BillingPlanService you do not intilize the userService due to it being a mock. You can simply set it on the mock and i think it should work in your context.
$userServiceMock = $this->mock(UserService::class, function ($mock) {
$mock->shouldReceive("getUsage")->andReturn([]);
});
$this->partialMock(BillingPlanService::class, function ($userServiceMock) use ($userServiceMock) {
$mock->set('userService', $userServiceMock);
$mock->shouldReceive("loadPlans")->andReturn([]);
});

the difference when using the initialization function in php

I'm not understanding how to use the initialization function in the code below. Can you explain it to me?
Class A
{
protected $classB;
public function __construct()
{
$this->classB = new ClassB();
}
}
Class A
{
protected $classB;
public function __construct(ClassB $classB)
{
$this->classB = $classB;
}
}
in the second way you always have to make your object like this.
$clasa = new ClassA($classb);
in the first way you are creating the object inside of the constructor.
the second way is an injection. and could be usefull when for example you need some attributes already seted in the object.

CIUnit Testing foostack

Is there anyone here used CIUnit?
Having trouble understanding it. T_T.
What I'm doing is pretty simple
E.g
I have a controller method myphp()
function myphp()
{
echo 'boom';
}
CI Unit Testing:
public function setUp()
{
// Set the tested controller
$this->CI = set_controller('home');
// date_default_timezone_set('America/Los_Angeles');
}
function testMyPhp()
{
$this->CI->myphp();
$out = output();
var_dump($out); //return empty eventhough function myphp is returning a string ('boom')
}
What happening.?? I just want to test whether I can fetch the output of my method myphp.

Zend Framework: How to stop dispatch/controller execution?

I have a Zend Framework controller with an editAction().
class WidgetController extends BaseController
{
public function editAction()
{
//code here
}
}
This controller extends a base controller which checks if the user is logged in before allowing the user to edit a record.
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
return $this->_redirect('/auth/login');
}
}
}
However, now that I am performing an AJAX request, I will be sending a JSON response back, so a redirect will no longer work. I need to stop further controller execution so I can immediately send a response:
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
if ($this->_request->isXmlHttpRequest()) {
$jsonData = Zend_Json::encode(array('error'=>'You are not logged in!'));
$this->getResponse()
->setHttpResponseCode(401)
->setBody($jsonData)
->setHeader('Content-Type', 'text/json');
//now stop controller execution so that the WidgetController does not continue
} else {
return $this->_redirect('/auth/login');
}
}
}
}
How can I stop controller execution?
I would define the user not being logged in and trying to make an XMLHTTPRequest as an exceptional state and let the error handler deal with it by throwing an exception (which stops dispatching of the current action). That way you are also able to handle other kinds of exceptions that might happen:
class BaseController extends Zend_Controller_Action
{
public function init()
{
if ($this->userNotLoggedIn()) {
if ($this->_request->isXmlHttpRequest()) {
throw new Exception('You are not logged in', 401);
} else {
return $this->_redirect('/auth/login');
}
}
}
}
class ErrorController extends Zend_Controller_Action
{
public function errorAction()
{
$errors = $this->_getParam('error_handler');
$exception = $errors->exception;
if ($this->_request->isXmlHttpRequest()) {
$jsonData = Zend_Json::encode($exception);
$jsonData = Zend_Json::encode(array('error'=> $exception->getMessage()));
$isHttpError = $exception->getCode() > 400 && $exception->getCode();
$code = $isHttpError ? $exception->getCode() : 500;
$this->getResponse()
->setHttpResponseCode($code)
->setBody($jsonData)
->setHeader('Content-Type', 'application/json');
} else {
// Render error view
}
}
}
I can think of many ways to stop the controller at this point in your code.
//now stop controller execution so that the WidgetController does not continue
For one, you can replace that line with this the following:
$this->getResponse()->sendResponse();
exit;
That may not be the cleanest but gets the job done rather nicely. The other option is going to be to change the action of the request in the init and let another action handle it. Replace that line with this:
$this->getRequest()->setActionName('invalid-user');
Because your already inside the dispatcher, it's going to run an action inside your action class whether you want it to or not. Trying to change the request in preDispatch will do nothing to change this dispatch. It's determined at this point to run an action inside your class. So, make an action to handle it.
public function invalidUserAction()
{
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
}
For more information see Zend_Controller_Dispatcher_Standard::dispatch.

How to run a single test method in simpletest unittest class?

This is my Unit Test class
<?
require_once '../simpletest/unit_tester.php';
require_once '../simpletest/reporter.php';
class Academic extends UnitTestCase
{
function setUp()
{
}
function tearDown()
{
}
function testAc1()
{
}
function testAc4()
{
}
function testAc7()
{
}
}
$test = new Academic();
$test->run(new HtmlReporter());
?>
When I run this script all methods viz., testAc1, testAc4, testAc7 etc are run.
Is there a way to execute just a single method ?
Thanks,
Shikhar
After digging through the SimpleTest source a bit, I have found the easiest way is to override the test's getTests() method as follows,
require_once('simpletest/autorun.php');
class Academic extends UnitTestCase
{
# ..
function testAc7()
{
}
function getTests()
{
return array("testAc7");
}
}
Here, simply including autorun.php as per usual, only the tests named in getTests() will be run.

Resources