phpunit with mocking and crawling

17
PHPUNIT Mocking and Crawling 1

Upload: trungx-trungx

Post on 13-Apr-2017

570 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: PHPUnit with Mocking and Crawling

1

PHPUNITMocking and Crawling

Page 2: PHPUnit with Mocking and Crawling

2

Unit Test là gì• Unit test là việc kiểm tra để đảm bảo rằng các đoạn chức

năng chạy đúng

• Lợi ích: mỗi khi thay đổi code chỉ cần run test là có thể kiểm tra lại xem có bị degrade phần nào ko

• Tuy nhiên: tốn effort để làm, nhàm chán

• Nên hay không?

=> Có...nếu làm tốt

Page 3: PHPUnit with Mocking and Crawling

3

PHP UNIT• Unit testing framework dành cho PHP

• Tạo bởi: Sebastian Bergmann

• Phiên bản mới nhất 5.1

• Github: https://github.com/sebastianbergmann/phpunit

• Cài đặt: composer global require "phpunit/phpunit=5.1.*"

Page 4: PHPUnit with Mocking and Crawling

4

Ví dụpublic function testAdd($a, $b, $expected) { $this->assertEquals($expected, $a + $b); }

$this->withSession([‘post_confirm' => 1]) ->visit(action(‘PostController@getConfirm')) ->see(‘Confirmed Post!’) ->see($input['email']);

$user = factory(\App\Models\User::class)->create(['nick_name' => 'Shanelle Marks']);$this->be($user);$this->visit(action('LoginController@getIndex')) ->seePageIs(action('TopPageController@getIndex'));

$this->post(action('LoginController@postChangePassword'), $input) ->seeInDatabase('users', [ 'password' => $hashPassword, ])

public function testGetIndexWithoutPermission(){ $administrator = factory(\App\Models\Administrator::class)->create(['role' => 3]); $this->actingAsAdmin($administrator) ->get(action('Admin\AdminArticleController@getIndex')) ->assertResponseStatus(403);}

Page 5: PHPUnit with Mocking and Crawling

5

Dom Crawler – hình dung

Page 6: PHPUnit with Mocking and Crawling

6

DOM Crawler• tự động phân tích dữ liệu từ nguồn nội dung sau đó bóc tách

những thông tin cần thiết theo tiêu chí mà nó được lập trình viên hệ thống thiết lập.

• Google Bot

• Ứng dụng với PHPUnit?

=> Phân tích và test HTML trả về• Symfony DomCrawler Component

=> http://symfony.com/doc/current/components/dom_crawler.html

Page 7: PHPUnit with Mocking and Crawling

7

Symfony DomCrawler$crawler = new Crawler($html);

foreach ($crawler as $domElement) { var_dump($domElement->nodeName);}

Khởi tạo

Duyệt bằng Xpath$crawler = $crawler->filterXPath('//div/p[@class="framgia"]/a');

Duyệt bằng jQuery-like selectors$crawler = $crawler->filter('div > p[class="framgia"] > a');

Node Traversing$crawler->filter('body > p')->eq(0);$crawler->filter('body > p')->first();$crawler->filter('body > p')->last();$crawler->filter('body > p')->siblings();$crawler->filter('body > p')->nextAll();$crawler->filter('body > p')->previousAll();$crawler->filter('body > p')->children();$crawler->filter('body > p')->parents();

Accessing Node Values$crawler->filter('body > p')->nodeName();$crawler->filter('body > p')->text();$crawler->filter('body > p')->html();$crawler->filter('body > p')->attr('name');

Page 8: PHPUnit with Mocking and Crawling

8

Crawler Example• Test image url

• Test hide div

• Test paging

$this->actingAs($user)->visit(action('RecordController@getDetail', $dietRecord->id)) ->crawler->filter('img.posted-photo') ->each(function (Crawler $node, $i) use($img) { $this->assertEquals($node->attr('src'), image_url($img->img_url)); });

$editButton = $this->actingAs($user2)->visit(route('mypage', $user->id)) ->see(trans('mypage/labels.edit_method_in_practice')) ->crawler->filter('#myPracticeListEdit');$this->assertContains('hide', $editButton->attr('class'));

$pagination = $this->actingAsAdmin($administrator) ->visit(action('Admin\AdminMemberController@getIndex', $input)) ->crawler->filter('ul.pagination');

$this->assertEquals(0, $pagination->count());

Page 9: PHPUnit with Mocking and Crawling

9

Mocking – hình dung

Page 10: PHPUnit with Mocking and Crawling

10

Mocking – tại sao cần• Test ko phụ thuộc các phần khác (Ex: Controller ->

Service -> DAO), hay người khác (module chưa làm xong)

• Có cần test Data access, Cache, Framework?

• Tạo ra 1 object chứa các thuộc tính, phương thức trả về kết quả theo ý muốn phục vụ việc test

• Mock object Framework hoạt động thông qua proxy, cần Dependency Injection

Page 11: PHPUnit with Mocking and Crawling

11

Lợi ích của Mock Object• Isolate - cô lập• Non-deterministic results – tránh những kết quả ko đoán

định được• Different states – tránh khác biệt trạng thái(3rd party API)• Speed – nhanh (CI run test each commit, DB so slow)• No existent objects – không phụ thuộc object khác• Mock Objects are simply an object that mimics the real

object. You can tell the mock object what methods you want to call, in what order and what parameters it should accept. You can then tell the Mock Object what you expect it to return.

Page 12: PHPUnit with Mocking and Crawling

12

Ví dụinterface ExtensionManagerInterface{ function checkExtension($fileName);}

class ExtensionManager implements ExtensionManagerInterface{ public function checkExtension($fileName) { //Some complex business logic might goes here. May be DB operation or file system handling return false; }}

class FileChecker{ private $objManager = null; //Default constructor function __construct() { $this->objManager = new ExtensionManager(); }

//Parameterized constructor function __construct(ExtensionManagerInterface $tmpManager) { $this->objManager = $tmpManager; }

public function checkFile($fileName) { //Check file size, file name length,... return $this->objManager->checkExtension($fileName); }}

Page 13: PHPUnit with Mocking and Crawling

13

Test//Stub implementation to bypass actual Extension manager class.class StubExtensionManager implements ExtensionManagerInterface{ public function checkExtension($fileName) { return true; }}

public function testCheckFileFunction(){ $stubExtensionManagerObject = new StubExtensionManager; $fileCheckerObject = new FileChecker($stubExtensionManagerObject); $this->assertTrue($fileCheckerObject->checkFile('framgia.com'));}

Page 14: PHPUnit with Mocking and Crawling

14

Mockery• Mockery is a powerful Mock Object framework for PHP

testing• Mockery offers a more natural language• Mockery does not override or conflict with PHPUnit's

built-in mocking functions; in fact, you can use them both at the same time• Install easy via composer • Mock a class - setUp()

• Close after used – teardown()

"mockery/mockery": "0.9.*",

$userServiceMock = Mockery::mock(\App\Services\UserService::class);

$this->app->instance(\App\Services\UserService::class, $userServiceMock);

Mockery::close();

Page 15: PHPUnit with Mocking and Crawling

15

Mockery usage• shouldReceive

• with/andReturn

• Get mock

public function testIndex(){ $this->mock->shouldReceive('all')->once();}

Cache::shouldReceive('get') ->times(3) ->with('key') ->andReturn('value');

->with(\Mockery::any()) OR ->with(anything())->with(\Mockery::on(closure))->with('/^foo/') OR ->with(matchesPattern('/^foo/'))->with(\Mockery::mustBe(2)) OR ->with(identicalTo(2))->with(\Mockery::not(2)) OR ->with(not(2))->with(\Mockery::anyOf(1, 2)) OR with(anyOf(1,2))->with(\Mockery::subset(array(0 => 'foo')))->with(\Mockery::contains(value1, value2))->with(\Mockery::hasKey(key))

->shouldReceive(method1, method2, ...)->andThrow(Exception)->andThrow(exception_name, message)->zeroOrMoreTimes()->atLeast()->times(3)->atMost()->times(3)->between(min, max)

$mock = \Mockery::mock('foo')->shouldReceive('foo')->andReturn(1)->getMock();

Page 16: PHPUnit with Mocking and Crawling

16

Mockery usage• Partial Mocks

$this->mock = Mockery::mock('MyClass[save, send]');

$this->mock = Mockery::mock('MyClass')->makePartial();

$this->mock ->shouldReceive('save') ->once() ->andReturn('true');

Constructor arguments$mock = \Mockery::mock('MyNamespace\MyClass[foo]', array($arg1, $arg2));

$experienceServiceMock = Mockery::mock(\App\Services\ExperienceService::class);$experienceServiceMock->shouldReceive('saveExperience')->times(1)->andReturn(false);$this->app->instance(\App\Services\ExperienceService::class, $experienceServiceMock);// Test$this->actingAs($user) ->withSession($sessionData) ->post(action('ExperienceController@postConfirm')) ->assertResponseStatus(500);

Page 17: PHPUnit with Mocking and Crawling

17

Thanks

• Thanks for coming!!!