Laravel 4 TDD Test failing - php

I All, I am trying really had to get in proper TDD but it is not smooth sailing.
This test keeps on failing and I can't figure out how to make it pass.
#>phpunit
PHPUnit 3.7.20 by Sebastian Bergmann.
Configuration read from /Users/ghall/Sites/laravel.hyundianet.hyundai.co.nz/phpunit.xml
<h2>Charts</h2>
<table class="table table-striped">
{"error":{"type":"ErrorException","message":"Invalid argument supplied for foreach()","file":"\/Users\/ghall\/Sites\/laravel.dev\/app\/storage\/views\/9fe7adcadbe887c8bce1c18e06defac2","line":8}}
I appears it's because the view it trying to render out something that does not exits from them mock
Route
App::bind('App\Models\Interfaces\ChartInterface', 'App\Models\Repositories\EloquentChartRepository');
Route::resource('chart', 'ChartController');
Controller
use App\Models\Interfaces\ChartInterface;
use App\Models\Repositories\EloquentChartRepository;
class ChartController extends BaseController
{
protected $layout = 'layouts.application';
protected $chart;
function __construct(ChartInterface $chart)
{
$this->chart = $chart;
// var_dump($chart);
}
public function index()
{
$charts = $this->chart->all();
$this->layout->content = View::make('chart.index')
->with('charts', $charts);
}
}
Repository
namespace App\Models\Repositories;
use App\Models\Interfaces\ChartInterface;
use Chart;
class EloquentChartRepository implements ChartInterface
{
public function all()
{
return Chart::all();
}
public function find($id)
{
return Chart::find($id);
}
}
Interface
namespace App\Models\Interfaces;
interface ChartInterface
{
public function all();
public function find($id);
}
Test
class ChartControllerTest extends TestCase
{
public function __construct()
{
$this->mock = Mockery::mock('App\Models\Interfaces\ChartInterface');
}
public function tearDown()
{
Mockery::close();
}
public function testIndex()
{
$this->mock
->shouldReceive('all')
->once()
->andReturn('charts');
$this->app->instance('App\Models\Interfaces\ChartInterface', $this->mock);
$this->call('GET', 'chart');
$this->assertViewHas('charts');
}
}
View
#if (!empty($charts))
#section('content')
<h2>Charts</h2>
<table class="table table-striped">
#foreach ($charts as $chart)
<tr>
<td>{{ $chart->id }}</td>
<td>{{ $chart->report_name }}</td>
<td>{{ $chart->description }}</td>
<td>{{ $chart->graphtype }}</td>
<td>{{ $chart->date_range }}</td>
<td>{{ $chart->user }}</td>
</tr>
#endforeach
</table>
#stop
#else
#section('content')
<h2>Nothing to display</h2>
#stop
#endif
NEW
I found the problem and it's in the Controller / view. When the test call the controller the controller returns the view with markup.
If I change the controller to then it works but this is not a good solution.
public function index()
{
$charts = $this->chart->all();
if(is_object($charts)){
$this->layout->content = View::make('chart.index')
->with('charts', $charts);
return;
}
return View::make('chart.test')->with('charts', $charts);
}

Inside of ChartControllerTest, in the test testIndex() the mock is returning a String and the view needs a array. Try with something like this:
$this->mock
->shouldReceive('all')
->once()
->andReturn(array());

You can check if variable supplied to view is array by using is_array function e.g in your view do
#if(is_array($charts))
#foreach ($charts as $chart)
<tr>
<td>{{ $chart->id }}</td>
<td>{{ $chart->report_name }}</td>
<td>{{ $chart->description }}</td>
<td>{{ $chart->graphtype }}</td>
<td>{{ $chart->date_range }}</td>
<td>{{ $chart->user }}</td>
</tr>
#endforeach
#endif
Regards

Related

How to solve this in Laravel 6? Trying to get property 'name' of non-object

My Model
class Purchase extends Model
{
public function supplier()
{
return $this->belongsTo(Supplier::class,'supplier_id','id');
}
public function unit()
{
return $this->belongsTo(Unit::class,'unit_id','id');
}
public function category()
{
return $this->belongsTo(Category::class,'category_id','id');
}
public function product()
{
return $this->belongsTo(Product::class,'product_id','id');
}
}
My Controller
class PurchaseController extends Controller
{
public function view()
{
$data['allData'] = Purchase::orderBy('id','desc')->get();
return view('backend.purchase.view-purchases', $data);
}
My View Page
#foreach($allData as $key => $purchase)
<tr>
<td>{{ $loop->index + 1 }}</td>
<td>{{ $purchase->purchase_no }}</td>
<td>{{ $purchase->product->name }}</td>
<td>{{ $purchase->unit->name }}</td>
<td>{{ $purchase->date }}</td>
and 2 more td for edit and delete
#endforeach
But there's still errors in all {{ $purchase-> example}}. I can't find the errors. If I check the dd() method right after the tr tag it works but it doesn't get the {{ $purchase-> example }}. I have the following error message:
Trying to get property 'name' of non-object (View: C:\xampp\htdocs\POS\resources\views\backend\purchase\view-purchases.blade.php).
enter image description here
Try loading the relations in the controller e.g.
$data['allData'] = Purchase::with('supplier', 'unit', 'category', 'product')->orderBy('id','desc')->get();
I would also advise you to change your controller view method body to the following.
$purchases = Purchase::with('supplier', 'unit', 'category', 'product')->orderBy('id','desc')->get();
return view('backend.purchase.view-purchases')->with(['purchases' => $purchases]);
So then in your view try to access it like the following.
#foreach($purchases as $purchase)
...
<td>{{ $purchase->purchase_no }}</td>
...
#endforeach

Call to undefined method Illuminate\Database\Query\Builder::with()

I'm trying to display the name of the category, but I get this error:
BadMethodCallException
Call to undefined method Illuminate\Database\Query\Builder::with()
AdminController.php
public function gamelist()
{
$categories = Category::all();
$home = DB::table('products')->with(['categories']);
return view('admin.gamelist', ['categories' => $categories, 'home' => $home, 'mode' => 'admin']);
}
Product.php
class Product extends Model
{
public function categories()
{
return $this->belongsTo('App\Category', 'category_id');
}
}
gamelist.blade.php
#foreach ($homes as $home)
<tr>
<td>{{ $home->id }}</td>
<td>{{ $home->name }}</td>
<td>{{ $home->categories->name}}</td>
<td>{{ $home->price }} €</td>
Can someone help me? Thank you
with is used to eager-load Eloquent relationships. By calling DB::table, you decided to use the query builder instead, and this one can't use Eloquent relationships.
You should replace
$home = DB::table('products')->with(['categories']);
by
$home = Product::with('categories')->get();

How to calculate sum for belongsTo model laravel

I need to get sum of amount for belongsTo model on laravel
Here is my code
Controller:
$users = AffiliationUser::whereAffiliationId(Auth::user()->id)
->with(['user' => function ($q){
$q->withCount(['billings'])->with(['affiliation_transactions']);
}])
->paginate(3);
//dd($users);
return view('affiliation.users', [
'users' => $users,
'current_balance' => 0,
]);
AffiliationUser model:
public function user() {
return $this->belongsTo('App\Models\Users');
}
User model:
public function billings() {
return $this->hasMany('App\Models\UserBillingSchedules', 'user_id');
}
public function affiliation_transactions() {
return $this->hasMany('App\Models\AffiliationTransaction', 'user_id');
}
View:
#foreach ($users as $user)
<tr class="even pointer">
<td class="a-center ">{{ $user->user->id }}</td>
<td class=" ">{{ $user->user->email }}</td>
<td class=" ">{{ $user->user->card_holder }}</td>
<td class=" ">{{ $user->user->billings_count }}</td>
<td class=" ">{{ $user->user->affiliation_transactions->sum('amount') }}</td>
</tr>
#endforeach
It is working good for me, but i don't like idea to get it on view.
{{ $user->user->affiliation_transactions->sum('amount') }}
Which one solution i can use also?
You can calculate the sum with withCount():
$users = AffiliationUser::whereAffiliationId(Auth::user()->id)
->with(['user' => function ($q) {
$q->withCount([
'billings',
'affiliation_transactions as amount' => function ($q) {
$q->select(DB::raw('coalesce(sum(amount), 0)'));
}
]);
}])
->paginate(3);
{{ $user->user->amount }}
Laravel allows you to create custom attributes (using the get[attributename]Attribute method in your Models easily which can be used to reduce the amount of code you need to write. In this case, you can do this:
User Model:
public function getTransactionCountAttribute() {
return $this->affiliation_transactions->sum('amount');
}
Now this can be acccessed with the following method in your code:
$user->user->transaction_count
Also, here's a little more information about Mutators, as these are named. Hope they can be useful to you :)
In User Model create a method like:
public function sum_amount() {
return this.affiliation_transactions->sum('amount');
}
then in your view...
{{ $user->user->sum_amount }}

Laravel - Undefined variable $data on view

I have a problem with this.
Undefined variable: acara (View:
/var/www/html/event_organizer/resources/views/admin/home.blade.php)
But I have declared $acara on the controller like this
Controller
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home')->with($data);
}
and the view like this
home.blade.php
#foreach($acara as $key)
<tbody>
<tr>
<td>{{ $key->nama_acara }}</td>
<td>{{ $key->kategori_acara }}</td>
<td>{{ $key->lokasi_acara }}</td>
</tr>
</tbody>
#endforeach
What's wrong with my code? Any idea? :)
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home', ['acara' => $data['acara'] ]);
}
OR
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home')->with('acara', $data['acara']);
}
OR
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home')->withAcara($data['acara']);
}
From this laravel official site Passing data to view, you can find all the way to send data from controller to view.
You need to change with() it's take an array
Change
with(['data'=>$data]);
or you can do like this also
withData($data);
Now you can receive the variable in view with $data and
in your case it will be
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home')->with(['acara'=>$data['acara']]);
}
Or
use App\events;
public function lihat_acara()
{
$data['acara'] = events::all();
return view('admin.home')->withAcara($data['acara']);
}
In the scenario above, the acara is not a variable you declared acara as an array key. I don't know why you had to do it like this. You can simply write the code like this:
$acara = Event::all();
OR
If you want to keep the controller like that, change the variable in #foreach loop:
#foreach($data['acara'] as $key)
<tbody>
<tr>
<td>{{ $key->nama_acara }}</td>
<td>{{ $key->kategori_acara }}</td>
<td>{{ $key->lokasi_acara }}</td>
</tr>
</tbody>
#endforeach

Laravel Undefined variable: books in View

The problem is undefined variable in view.
My controller:
use App\Book;
class bookController extends Controller
{
public function index()
{
$books = Book::all();
return view('frontend.index')->with('books', $books);
}
}
I get undefined variable books;
I was searching here and on the web and tried many things and I still get that error.
Not sure why. Can someone help me?
Thank you
EDIT:
View:
#foreach ($books as $key => $book)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $book->title }}</td>
<td>{{ $book->description }}</td>
</tr>
#endforeach
First of all your class name must start with capital letter...
Try this:
return view('frontend.index', ['books' => $books]);
instead of
return view('frontend.index')->with('books', $books);
Try this:
return view('frontend.index')->with(compact($books));
Try this
use App\Book;
class bookController extends Controller
{
public function index()
{
$books = Book::all();
$data['books'] = $books; //You may put other values too in $data array
return view('frontend.index', $data);
}
}

Categories