Not able to mock Laravel Model method - laravel

I am currently writing a test to test a model method.
My model Store has this method:
public function hourTemplate() {
return $this->belongsTo(HourTemplate::class);
}
I have a test as well with this code in setUp method:
public function setUp() : void
{
parent::setUp();
$this->storeMock = Mockery::mock(StoreModel::class)->makePartial();
app()->instance(StoreModel::class, $this->storeMock);
}
And test method is like this:
public function test_getStoreHoursArray_when_hour_isNull() {
$this->storeMock->shouldReceive('hourTemplate')->andReturn(new HourTemplate());
dump((new StoreModel())->hourTemplate);
}
But the returned value is null.

You should retrieve the mocked instance from the container
$mockedModel = app()->make(StoreModel::class);

Related

phpunit : test api and mock some method in same controller, but mocked method is not work

controller code
class testController extends \Illuminate\Routing\Controller
{
public function test1() {
$a = $this->test2();
...
}
protected function test2() {
return '123';
}
}
unit test code
class Test extends TestCase
{
public function unittest()
{
$mockController = \Mockery::mock('App\Http\Controllers\testController')->makePartial()->shouldAllowMockingProtectedMethods();
$mockController ->shouldReceive('test2')->andReturn('456');
$response = $this->json('GET', action('testController#test1'));
$response->assertStatus(200);
}
}
when do unit test, test2 method always return 123, not 456
Anything help? Thanks.
It's not clear what $this->json() does internally (it's not a part of plain PHPUnit), but anyway, the problem is probably that you don't inject your $mockController anywhere, and thus the original controller is requested by unit test.

How to write a custom function in a model?

There is a model data:
class Order extends Model
{
}
How to write a custom method inside the Order class so that it can be called in constructor like this:
Order::myMethod()
Order->myMethod()
Where myMethod is:
public function myMethod() {
return DB::query(<SQL QUERY>);
}
Purpose is to move SQL queries inside model's class, that don't mess this code in controllers.
Rather create a custom function in Model, You can use traits to achieve the desired output.
Please follow either steps:-
https://medium.com/#kshitij206/traits-in-laravel-5db8beffbcc3
https://www.conetix.com.au/blog/simple-guide-using-traits-laravel-5
Guess you are asking about the static functions:
class Order extends Model {
public static function myMethod() {
}
}
and you can call it anywhere like
Order::myMethod();
You can achieve the desired behavior using magic methods __call and __callStatic
if your real method is static you can use __call() to intercept all "non static" calls and use it to call the static and use __callStatic to forward the calls to a new instance to that class .
Your methods should be always static because if a non static method exists and you are calling it statically php raises an error
Non-static method Foo::myMethod() should not be called statically
No problem if your method is static
class Order extends Model {
public static function myMethod() {
return static::query()->where(...)->get(); // example
}
public function __call($name, $arguments) {
return forward_static_call_array([__CLASS__, $name], $arguments);
}
public static function __callStatic($name, $arguments) {
return call_user_func_array([app(__CLASS__), $name], $arguments);
}
}
(new Order())->myMethod();
Order::myMethod();
I can't understand your exact problem is. but if you are using laravel, then you can write custom method inside the ABC model like this
class ABC extends Model
{
//here is your fillable array;
public function abc()
{
//Here is your Eloquent statement or SQL query;
}
}
just call this abc() method inside the controller like this
use ABC;
class AbcController extends Controller
{
private $_abc; // it is private variable
// this is constructor
public function __construct(ABC $abc)
{
$this->_abc= $abc;
}
public function abcMethod()
{
$this->_abc->abc();
}
}
Thanks
I don't believe I'm understanding your intention. You've stated:
Purpose is to move SQL queries inside model's class, that don't mess this code in controllers.
Why does the Order->myMethod() need calling inside the constructor? If you're trying to design your data access layer to work efficiently, you can use data repositories.

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!

Play framework Testing controller

I am trying to test a controller using callAction
in ApplicationTest.java's testAction() method:
Result result =
callAction(controllers.routes.ref.Application.action(463), request);
testAction(int) refers to some of the fields(mySpringService) in Application controller. How and where these fields to be instantiated? Can I have setup() in AplicationTest.java??
public class Application extends Controller {
#Autowired privateMySpringService mySpringService;
public Result action(int waterQualityId){
mySpringService.doSomeMath(); return ok(); }
}
Any help is appreciated.

ZF2 using FilterProviderInterface to filter class method

I have a model class witch basically is the fields from a database table with getter and setters.
class RealEstate extends BaseModel implements FilterProviderInterface
{
public $cityId;
public $stateId;
...
public $transferFields = array();
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
public function setTransferFields($transferFields)
{
$this->transferFields = $transferFields;
}
public function getTransferFields()
{
return $this->transferFields;
}
...
}
In my BaseTableGateway class I have a method save which takes this model object and extracts the data using get methods into an array.
$hydrator = new ClassMethods(false);
$model_data = $hydrator->extract($model);
I need the getTransferFields() method to bind the object to my form but I dont need it to be in the final array (be excluded while extracting).
public function getFilter()
{
return new MethodMatchFilter('getTransferFields');
}
This method does exactly what I want but only for 1 method. I can't find out how to filter more than 1 method. Does anyone know how this would be achieved?
Simply return a FilterComposite object. The FilterComposite implements FilterInterface and is treated the same as the MethodMatchFilter.
For example:
public function getFilter()
{
$myFilters = new FilterComposite();
$myFilters->addFilter('someParam', new MethodMatchFilter('getSomeParam'));
$myFilters->addFilter('someOtherParam', new MethodMatchFilter('getSomeOtherParam'));
return $myFilters;
}

Resources