CIUnit Testing foostack - codeigniter

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.

Related

Is it possible to retrieve a value from a redirect in another class before performing the redirect?

I am currently working with a controller, OnboardingController.php. This controller calls another method in a different class, let's call it OnboardingService.php, so for example:
OnboardingController
public function doThing()
{
return $this->doAnotherThing();
}
OnboardingService
public function doAnotherThing()
{
return redirect('/')->with(['propertyA' => 'valueA']);
}
Would I be able to access propertyA in OnboardingController before returning the redirect? And if so, how would I access that property?
e.g.
OnboardingController
public function doThing()
{
$doAnotherThing = $this->doAnotherThing();
Log::info($doAnotherThing->propertyA);
return $doAnotherThing;
}
I am currently using Laravel 6.
You're using redirect(...)->with(...) to flash propertyA, so propertyA should be accessible from the session
public function doThing()
{
$doAnotherThing = $this->doAnotherThing();
Log::info(session()->get('propertyA'));
return $doAnotherThing;
}

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([]);
});

how to write Feature Test for -excel document upload check

i'm using https://docs.laravel-excel.com/ for uploading Excel and then display on view
here is my controller
public function import()
{
$rows= Excel::toArray(new ProfitAndLosImport, request()->file('pl'));
return view("pl")->with(compact('rows'));
}
how to write test for checking this process ?
Any help would be much appreciated
i'm using this but it's working
public function testUpload()
{
Excel::fake();
$this->actingAs(factory('App\User')->create());
$testFile = UploadedFile::fake()->create('borrowers.xlsx');
$response =$this->post('pl',['pl'=>$testFile]);
Excel::assertImported('create_terms.xls', function(ProfitAndLosImport $import) {
return true;
});
}

How to call dispatchShell on same shell for another method?

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.

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.

Resources