Skip to content

[Tamnx] Unit test homework #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

namespace Tests\Feature;

use Modules\Exercise03\Http\Controllers\ProductController;
use Modules\Exercise03\Http\Requests\CheckoutRequest;
use Modules\Exercise03\Services\ProductService;
use Tests\TestCase;

class ProductControllerTest extends TestCase
{
protected $productController;
protected $productService;

protected function setUp(): void
{
parent::setup();

$this->productService = $this->mock(ProductService::class);
$this->productController = new ProductController(
$this->productService
);
}

public function test_index_return_view_success()
{
$products = [];
$this->productService->shouldReceive('getAllProducts')->andReturn($products);
$response = $this->productController->index();
$this->assertEquals('exercise03::index', $response->getName());
$this->assertEquals(compact('products'), $response->getData());

}

public function test_function_checkout()
{
$mockRequest = $this->mock(CheckoutRequest::class);
$mockRequest->shouldReceive('input')->andReturn([]);
$this->productService->shouldReceive('calculateDiscount')->andReturn(5);
$response = $this->productController->checkout($mockRequest);
$this->assertEquals(['discount' => 5], $response->getOriginalContent());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Tests\Feature;

use Illuminate\Support\Facades\Validator;
use Modules\Exercise03\Http\Requests\CheckoutRequest;
use Tests\TestCase;

class CheckoutRequestTest extends TestCase
{
protected $checkoutRequest;

protected function setUp(): void
{
parent::setUp();

$this->checkoutRequest = new CheckoutRequest();
}

public function test_validate_success()
{
$input = [
'total_products' => [
'product_1' => 0,
'product_2' => 1
]
];

$validator = Validator::make($input, $this->checkoutRequest->rules());
$this->assertTrue($validator->passes());
}

/**
* @dataProvider provider_test_validation_fail
*/
public function test_validation_fail($attribute, $inputs)
{
$validator = Validator::make($inputs, $this->checkoutRequest->rules());
$this->assertFalse($validator->passes());
$this->assertArrayHasKey($attribute, $validator->getMessageBag()->getMessages());
}

function provider_test_validation_fail()
{
return [
[
'total_products',
[
'total_products' => null,
]
],
['total_products',
[
'total_products' => '',
]
],
];
}

/**
* @dataProvider provider_test_integer_validation_fail
*/
public function test_validation_fail_not_integer($attribute, $inputs)
{
$validator = Validator::make($inputs, $this->checkoutRequest->rules());
$this->assertFalse($validator->passes());
$attribute = $attribute.'.total_products_0';
$this->assertArrayHasKey($attribute, $validator->getMessageBag()->getMessages());
}

function provider_test_integer_validation_fail()
{
return [
[
'total_products',
[
'total_products' => [
'total_products_0' => '1x'
],
]
],
[
'total_products',
[
'total_products' => [
'total_products_0' => -1
],
]
],
];
}
}
28 changes: 28 additions & 0 deletions Modules/Exercise03/Tests/Unit/Models/ProductTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Modules\Exercise03\Tests\Unit\Models;

use Modules\Exercise03\Models\Product;
use Tests\TestCase;

class ProductTest extends TestCase
{
public function test_product_fields()
{
$inputs = [
'name' => 'product',
'type' => Product::OTHER_TYPE,
];
$atmModel = new Product();
$atmModel->fill($inputs);
$this->assertEquals($inputs['name'], $atmModel->name);
$this->assertEquals($inputs['type'], $atmModel->type);
}

public function test_product_new_factory()
{
$product = Product::factory()->make();

$this->assertInstanceOf(Product::class, $product);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Modules\Exercise03\Tests\Unit\Repositories;

use Modules\Exercise03\Models\Product;
use Modules\Exercise03\Repositories\ProductRepository;
use Tests\TestCase;

class ProductRepositoryTest extends TestCase
{
protected $productRepository;
private $productModel;

protected function setUp(): void
{
parent::setUp();

$this->productModel = $this->mock(Product::class);
$this->productRepository = new ProductRepository(
$this->productModel
);
}

public function test_function_all()
{
$expected = ['products' => ['items' => []]];
$this->productModel->shouldReceive('all')->andReturn($expected);

$this->assertEquals($expected, $this->productRepository->all());
}
}
67 changes: 67 additions & 0 deletions Modules/Exercise03/Tests/Unit/Services/ProductServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Tests\Unit\Services;

use Modules\Exercise03\Models\Product;
use Modules\Exercise03\Repositories\ProductRepository;
use Modules\Exercise03\Services\ProductService;
use Tests\TestCase;
use InvalidArgumentException;

class ProductServiceTest extends TestCase
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ở đây thiếu miss mất 1 case.
Giả sử các trường hợp dưới đây không tồn tại thì ra sao?

$totalProducts[Product::CRAVAT_TYPE] 
$totalProducts[Product::OTHER_TYPE]
$totalProducts[Product::WHITE_SHIRT_TYPE]

Ngoài thì cũng nên để ý các trương logic so sánh >= hiện tại chỉ đang test các trường hợp > nhưng đối với các trường hợp = thì đang không test

{
protected $productService;
protected $productRepository;

protected function setUp(): void
{
parent::setUp();

$this->productRepository = $this->mock(ProductRepository::class);
$this->productService = new ProductService(
$this->productRepository
);
}

public function test_function_get_all_products()
{
$expected = ['products' => ['items']];
$this->productRepository->shouldReceive('all')->andReturn($expected);

$this->assertEquals($expected, $this->productService->getAllProducts());
}

public function test_calculate_discount_return_throw_exception()
{
$this->expectException(InvalidArgumentException::class);
$this->productService->calculateDiscount([
Product::CRAVAT_TYPE => -1,
Product::WHITE_SHIRT_TYPE => -1,
Product::OTHER_TYPE => -1,
]);
}

public function test_calculate_discount_return_white_shirt_discount()
{
$expected = ProductService::CRAVAT_WHITE_SHIRT_DISCOUNT;
$result = $this->productService->calculateDiscount([
Product::CRAVAT_TYPE => 2,
Product::WHITE_SHIRT_TYPE => 1,
Product::OTHER_TYPE => 0,
]);

$this->assertEquals($expected, $result);
}

public function test_calculate_discount_return_discount_with_quantity_discount()
{
$expected = ProductService::QUANTITY_DISCOUNT + ProductService::CRAVAT_WHITE_SHIRT_DISCOUNT;
$result = $this->productService->calculateDiscount([
Product::CRAVAT_TYPE => 2,
Product::WHITE_SHIRT_TYPE => 2,
Product::OTHER_TYPE => 5,
]);

$this->assertEquals($expected, $result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Tests\Feature\Http\Controllers;

use Modules\Exercise04\Http\Controllers\CalendarController;
use Modules\Exercise04\Services\CalendarService;
use Tests\TestCase;

class CalendarControllerTest extends TestCase
{
protected $calendarService;
protected $calendarController;

protected function setUp(): void
{
parent::setup();

$this->calendarService = $this->mock(CalendarService::class);
$this->calendarController = new CalendarController(
$this->calendarService
);
}
public function test_index_return_view_success()
{
$expected = CalendarService::COLOR_BLACK;
$this->calendarService->shouldReceive('getDateClass')->andReturn($expected);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trong controller này có logic, nên phải làm sao test đưuọc cả logic đấy. Muốn test được logic đấy thì có 2 cách
1 là cái mock này không nên chỉ shouldReceiveandReturn luôn.
Mình nên làm để biết thêm là cái method getDateClass gọi bao nhiêu lần và những tham số truyền vào là gì
2 là
$response->assertViewHas('calendars'); thì mình phải assert xem cả cái data của nó nữa

$response = $this->calendarController->index();

$this->assertEquals('exercise04::calendar', $response->getName());
$this->assertArrayHasKey('calendars', $response->getData());
}
}
52 changes: 52 additions & 0 deletions Modules/Exercise04/Tests/Unit/Services/CalendarServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Tests\Unit\Services;

use Carbon\Carbon;
use Modules\Exercise04\Services\CalendarService;
use PHPUnit\Framework\TestCase;

class CalendarServiceTest extends TestCase
{
protected $calendarService;

protected function setUp(): void
{
parent::setup();

$this->calendarService = new CalendarService();
}

/**
* @dataProvider provider_return_class
*/
public function test_function_get_date_class($date, $class)
{

$response = $this->calendarService->getDateClass($date, ['2021-05-04']);

$this->assertEquals($class, $response);
}

public function provider_return_class()
{
return [
[
Carbon::createFromDate(2021, 5, 1),
CalendarService::COLOR_BLUE
],
[
Carbon::createFromDate(2021, 5, 2),
CalendarService::COLOR_RED
],
[
Carbon::createFromDate(2021, 5, 4),
CalendarService::COLOR_RED
],
[
Carbon::createFromDate(2021, 5, 5),
CalendarService::COLOR_BLACK
],
];
}
}
Loading