SlideShare ist ein Scribd-Unternehmen logo
1 von 14
PhpUnit модульне тестування
Короткий опис модульного тестування з використанням
фреймворка PhpUnit
1. Типи тестів:
• Модульні тести (юніт тести)
Тести найменших одиниць функціональності (модулів). Перевірка, чи функція, яка тестується
виконує саме те, для чого вона реалізована.
• Інтеграційні тести
Поєднує різні одиниці коду (різні модулі). Перевірка чи правильно працює їхня комбінація.
• Системні тести
• Прийомочні тести
2. Структура папок
tests/
unit/
Http/
Controllers/
TenderControllerTest.php
integration/
TenderStatusesTest.php
helpers/
UserHelper.php
3. Приклад модульного теста
use path/Default.php // підключення файла для тесту
class defaultTests extends PHPUnit_Framework_TestCase
{
private $default;
protected function setUp() // метод, який викликається перед кожним тестом (незалежно від кількості)
{
$this->default = new Default();
}
protected function tearDown() // метод, який викликається після кожного теста (незалежно від кількості)
{
$this-> default = NULL;
}
public function testAdd() // метод тест для метода add() класса Default()
{
$result = $this->default->add(1, 2);
$this->assertEquals(3, $result); //перевірка чи метод повернув правильний результат
}
}
4. Запуск і результат тесту:
phpunit tests/DefaultTest.php
PHPUnit 3.7.32 by Sebastian Bergmann.
.
Time: 31ms, Memory: 2.25Mb
OK (1 test, 1 assertion)
5. Використання різних наборів вхідних
данних
Без використання DataProvider
public function testAdd()
{
$result = $this->calculator->add(1, 2);
$this->assertEquals(3, $result);
}
public function testAddWithZero()
{
$result = $this->calculator->add(0, 0);
$this->assertEquals(0, $result);
}
public function testAddWithNegative()
{
$result = $this->calculator->add(-1, -1);
$this->assertEquals(-2, $result);
}
6. Використання різних наборів вхідних
данних
Метод, який являється DataProvider’ом, має повертати масив масивів.
Метод, який являється тестом буде викликатись декілька раз з кожним масивом, в якості аргументів будуть
передаватись вміст масиви.
Ключові моменти для використання dataProvider:
- метод dataProvider має бути публічним.
- метод dataProvider має повертати масив зібраних данних
- метод теcта має використовувати аннотоацію @dataProvider, щоб вказати, який метод має використовуватись в
якості dataProvider
7. Використання DataProvider
public function addDataProvider() {
return array(
array(1,2,3),
array(0,0,0),
array(-1,-1,-2),
);
}
/**
* @dataProvider addDataProvider
*/
public function testAdd($a, $b, $expected)
{
$result = $this->calculator->add($a, $b);
$this->assertEquals($expected, $result);
}
8. Asserts
assertEquals(‘foo’, ‘foo’)
assertTrue(!empty($result))
assertFalse(!empty($result))
assertArrayHasKey('foo', ['bar' => 'baz'])
assertClassHasAttribute('foo', stdClass::class)
assertContains(4, [1, 2, 3]);
assertCount(0, ['foo'])
assertDirectoryExists('/path/to/directory')
assertDirectoryIsReadable('/path/to/directory')
assertFileExists('/path/to/file')
assertNull('foo')
assertRegExp('/foo/', 'bar')
https://phpunit.de/manual/current/en/appendixes.assertions.html
9. Mock
Іноді при тестуванні нам потрібно використовувати обєкти, поведінку яких ми не можемо контролювати. Для рішення цієї проблеми
можна використовувати mock-обєкти.
Наприклад нам потрібно працювати з базою данних. Наприклад є метод який робить важкий запрос в базу данних, який
виконується не часто і для нашого тесту не потрібно відтворювати сам запрос, але результат запросу потрібен.
Метод getMock створює mock-обєкт з таким самим набором методів, як і звичайний обєкт классу Database. Всі методи, за
замовченням, будуть повертати null, але ми можемо перегрузити потрібний нам метод.
9.1. Приклад використання Mock-обєкта
class Database {
/**
* повільний метод який буде викоритсаний
*/
public function reallyLongTime() {
$results = array(
array(1, 'test', 'foo value')
);
sleep(1000);
return $results;
}
}
Class DatabaseTest extends PHPUnit_Framework_TestCase {
private $db = null;
public function setUp() {
$this->db = new Database();
}
public function tearDown() {
unset($this->db);
}
public function testReallyLongReturn() {
$mock = $this->getMock('Database');
$result = array(
array(1, 'foo', 'bar test')
);
$mock->expects($this->any())
->method('reallyLongTime')
->will($this->returnValue($result));
$return = $mock->reallyLongTime();
$this→assertTrue(count($result) == 3);
}
}

При кожному виклику метода reallyLongTime обєкта $mock буде повертатись значення змінної $result, замість реального виконання методу.
9.2 MockBuilder
При роботі з MockBuilder першим методом в ланцюгу викликів має бути getMockBuilder(), а останнім — getMock(). Наприклад, в наступному прикладі ми
створюємо mock-обєкт, которий не використовує конструктор, а також вимикає autoload:
function testReallyLongRunBuilder() {
$stub = $this->getMockBuilder('Database')
->setMethods(array(
'reallyLongTime'
))
->disableAutoload()
->disableOriginalConstructor()
->getMock();
$result = array(array(1, 'foo', 'bar test'));
$stub->expects($this->any())
->method('reallyLongTime')
->will($this->returnValue($result));
$this->assertGreaterThan(0, count($return));
}
public function getMock(
$originalClassName, // назва оригінального класса, для якого буде створений Mock обєкт
$methods = array(), // Массив методів для заміни, якщо вказати null методи будуть без підміни
array $arguments = array(), // аргументи, які передаються в конструктор
$mockClassName = '', // можна вказати імя Mock класа
$callOriginalConstructor = true, // відключити __construct()
$callOriginalClone = true, // відключити __clone()
$callAutoload = true // відключити __autoload()
);
$mock = $this->getMockBuilder('MyClass')
->setMethods(null)
->setConstructorArgs(array())
->setMockClassName('')
->disableOriginalConstructor()
->disableOriginalClone()
->disableAutoload()
->getMock();
Послідовність методів починається з метода getMockBuilder() и закінчується методом getMock() —
ці методи обовязкові.
9.3. Очікування виклику методів
PHPUnit дозволяє нам контролювати кількість і порядок викликів підмінених методів. Для цього використовується конструкція
expects() з вказуванням потрібного метода за допомогою - method().

public function test_process() {

$mock = $this->getMock('MyClass', array('getTemperature', 'getWord', 'showWord'));

$mock->expects($this->once())->method('getTemperature');

$mock->expects($this->once())->method('showWord');

$mock->expects($this->once())->method('getWord');

$mock->process();

}


Результат виконання этого теста будет успешным, если при вызове метода process() произойдет однократный вызов трех
перечисленных методов: getTemperature(), getWord(), showWord(). Обратите внимание, что в тесте проверка вызова getWord()
стоит после проверки вызова showWord(), хотя в тестируемом методе наоборот. Все верно, ошибки здесь нет. Для контроля
порядка вызова методов в PHPUnit используется другая конструкция — at(). Поправим немного код нашего теста так чтобы
PHPUnit проверил заодно очередность вызова методов:

public function test_process() {

$mock = $this->getMock('MyClass', array('getTemperature', 'getWord', 'showWord'));

$mock->expects($this->at(0))->method('getTemperature');

$mock->expects($this->at(2))->method('showWord');

$mock->expects($this->at(1))->method('getWord');

$mock->process();

}


Помимо упомянутых once() и at() для тестирования ожиданий вызовов в PHPUnit есть также следующие конструкции: any(),
never(), atLeastOnce() и exactly($count). Их названия говорят сами за себя.

Weitere ähnliche Inhalte

Was ist angesagt? (20)

JavaScript. Lectures. part 1. basis
JavaScript. Lectures. part 1. basisJavaScript. Lectures. part 1. basis
JavaScript. Lectures. part 1. basis
 
tsql
tsqltsql
tsql
 
08 Functions
08 Functions08 Functions
08 Functions
 
SQL: Indexes, Select operator
SQL: Indexes, Select operatorSQL: Indexes, Select operator
SQL: Indexes, Select operator
 
SQL Grouping, Joins
SQL Grouping, JoinsSQL Grouping, Joins
SQL Grouping, Joins
 
Coding for Future in Lutsk. JavaScript. Part 6
Coding for Future in Lutsk. JavaScript. Part 6Coding for Future in Lutsk. JavaScript. Part 6
Coding for Future in Lutsk. JavaScript. Part 6
 
Модулі Python
Модулі PythonМодулі Python
Модулі Python
 
01 c# basics
01 c# basics01 c# basics
01 c# basics
 
Coding for Future in Lutsk. JavaScript. Part 3
Coding for Future in Lutsk. JavaScript. Part 3Coding for Future in Lutsk. JavaScript. Part 3
Coding for Future in Lutsk. JavaScript. Part 3
 
Design patterns part 2
Design patterns part 2Design patterns part 2
Design patterns part 2
 
Lect 6 prolog
Lect 6 prologLect 6 prolog
Lect 6 prolog
 
"Is there life in react without redux" by Babich Sergiy. OdessaJS'2021
"Is there life in react without redux" by Babich Sergiy. OdessaJS'2021"Is there life in react without redux" by Babich Sergiy. OdessaJS'2021
"Is there life in react without redux" by Babich Sergiy. OdessaJS'2021
 
передача параметрів в функції
передача параметрів в функціїпередача параметрів в функції
передача параметрів в функції
 
09 Object And Class Hierarchy
09 Object And Class Hierarchy09 Object And Class Hierarchy
09 Object And Class Hierarchy
 
PHP
PHPPHP
PHP
 
лекция 14 phylo
лекция 14 phyloлекция 14 phylo
лекция 14 phylo
 
08 Templates
08 Templates08 Templates
08 Templates
 
1
11
1
 
Design patterns part 1
Design patterns part 1Design patterns part 1
Design patterns part 1
 
Theme20_ajax
Theme20_ajaxTheme20_ajax
Theme20_ajax
 

Andere mochten auch

Towards a Better Understanding of the Impact of Experimental Components on De...
Towards a Better Understanding of the Impact of Experimental Components on De...Towards a Better Understanding of the Impact of Experimental Components on De...
Towards a Better Understanding of the Impact of Experimental Components on De...Chakkrit (Kla) Tantithamthavorn
 
Pastoral. Trobada intercol.legial. Fem Camí 2017
Pastoral. Trobada intercol.legial. Fem Camí 2017Pastoral. Trobada intercol.legial. Fem Camí 2017
Pastoral. Trobada intercol.legial. Fem Camí 2017infoescolapiesfigueres
 
Ingeniería mecánica estática willian f. riley
Ingeniería mecánica estática willian f. rileyIngeniería mecánica estática willian f. riley
Ingeniería mecánica estática willian f. rileyJosé Aravena Magofke
 
Ssit informacoesgerenciais 5
Ssit informacoesgerenciais 5Ssit informacoesgerenciais 5
Ssit informacoesgerenciais 5Nauber Gois
 
Silo vertical cgr cv
Silo vertical cgr cvSilo vertical cgr cv
Silo vertical cgr cvJaime Sanchez
 
Як функціонує державна влада в Україні
Як функціонує державна влада в УкраїніЯк функціонує державна влада в Україні
Як функціонує державна влада в Україніradaprogram
 
Executive summary agrivol it rev a
Executive summary agrivol it rev aExecutive summary agrivol it rev a
Executive summary agrivol it rev aFPasquazi
 
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-ups
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-upsArtificial Intelligence in Medical Imaging: An Analysis of Funding for Start-ups
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-upsSimon Harris
 
съчинение по наблюдение
съчинение по наблюдениесъчинение по наблюдение
съчинение по наблюдениеdaniela velcheva
 
Derecho Procesal Penal II
Derecho Procesal Penal IIDerecho Procesal Penal II
Derecho Procesal Penal IIYoselinCaruciG
 
Presentación Prezi
Presentación Prezi Presentación Prezi
Presentación Prezi robertoyalex
 
Csi pavia notizie_n_10_del_14.03.17
Csi pavia notizie_n_10_del_14.03.17Csi pavia notizie_n_10_del_14.03.17
Csi pavia notizie_n_10_del_14.03.17CSI PAVIA
 
A importância da oratória em todas as áreas da vida
A importância da oratória em todas as áreas da vidaA importância da oratória em todas as áreas da vida
A importância da oratória em todas as áreas da vidaSamanta de Souza Silva
 
Relatoria de la biografia
Relatoria de la biografiaRelatoria de la biografia
Relatoria de la biografiasara muñoz
 

Andere mochten auch (18)

Towards a Better Understanding of the Impact of Experimental Components on De...
Towards a Better Understanding of the Impact of Experimental Components on De...Towards a Better Understanding of the Impact of Experimental Components on De...
Towards a Better Understanding of the Impact of Experimental Components on De...
 
Pastoral. Trobada intercol.legial. Fem Camí 2017
Pastoral. Trobada intercol.legial. Fem Camí 2017Pastoral. Trobada intercol.legial. Fem Camí 2017
Pastoral. Trobada intercol.legial. Fem Camí 2017
 
Ingeniería mecánica estática willian f. riley
Ingeniería mecánica estática willian f. rileyIngeniería mecánica estática willian f. riley
Ingeniería mecánica estática willian f. riley
 
Ssit informacoesgerenciais 5
Ssit informacoesgerenciais 5Ssit informacoesgerenciais 5
Ssit informacoesgerenciais 5
 
Calcium and Hypertension
 Calcium and Hypertension  Calcium and Hypertension
Calcium and Hypertension
 
Motores universais
Motores universaisMotores universais
Motores universais
 
Hakikat supervisi kependidikan 2
Hakikat supervisi kependidikan 2Hakikat supervisi kependidikan 2
Hakikat supervisi kependidikan 2
 
Silo vertical cgr cv
Silo vertical cgr cvSilo vertical cgr cv
Silo vertical cgr cv
 
Як функціонує державна влада в Україні
Як функціонує державна влада в УкраїніЯк функціонує державна влада в Україні
Як функціонує державна влада в Україні
 
Executive summary agrivol it rev a
Executive summary agrivol it rev aExecutive summary agrivol it rev a
Executive summary agrivol it rev a
 
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-ups
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-upsArtificial Intelligence in Medical Imaging: An Analysis of Funding for Start-ups
Artificial Intelligence in Medical Imaging: An Analysis of Funding for Start-ups
 
съчинение по наблюдение
съчинение по наблюдениесъчинение по наблюдение
съчинение по наблюдение
 
Derecho Procesal Penal II
Derecho Procesal Penal IIDerecho Procesal Penal II
Derecho Procesal Penal II
 
Presentación Prezi
Presentación Prezi Presentación Prezi
Presentación Prezi
 
Csi pavia notizie_n_10_del_14.03.17
Csi pavia notizie_n_10_del_14.03.17Csi pavia notizie_n_10_del_14.03.17
Csi pavia notizie_n_10_del_14.03.17
 
A importância da oratória em todas as áreas da vida
A importância da oratória em todas as áreas da vidaA importância da oratória em todas as áreas da vida
A importância da oratória em todas as áreas da vida
 
Autobiografía
AutobiografíaAutobiografía
Autobiografía
 
Relatoria de la biografia
Relatoria de la biografiaRelatoria de la biografia
Relatoria de la biografia
 

Ähnlich wie Phpunit модульне тестування

Php unit. Y. Muzychushun
Php unit. Y. MuzychushunPhp unit. Y. Muzychushun
Php unit. Y. MuzychushunHRdepartment
 
WordPress meetup Kyiv - Starting theme
WordPress meetup Kyiv - Starting themeWordPress meetup Kyiv - Starting theme
WordPress meetup Kyiv - Starting themeTrilipuT
 
05 Operations And Utilities
05 Operations And Utilities05 Operations And Utilities
05 Operations And Utilitiesolegapster
 
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...Igor Bronovskyy
 
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...Igor Bronovskyy
 
02 Copying Objects
02 Copying Objects02 Copying Objects
02 Copying Objectsolegapster
 
11 Iterated Containers
11 Iterated Containers11 Iterated Containers
11 Iterated Containersolegapster
 
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5Nikita Pavliuchenko
 
Advanced C#. Part 2
Advanced C#. Part 2Advanced C#. Part 2
Advanced C#. Part 2eleksdev
 

Ähnlich wie Phpunit модульне тестування (19)

Php unit. Y. Muzychushun
Php unit. Y. MuzychushunPhp unit. Y. Muzychushun
Php unit. Y. Muzychushun
 
Tdd, ти де?
Tdd, ти де?Tdd, ти де?
Tdd, ти де?
 
WordPress meetup Kyiv - Starting theme
WordPress meetup Kyiv - Starting themeWordPress meetup Kyiv - Starting theme
WordPress meetup Kyiv - Starting theme
 
05 Operations And Utilities
05 Operations And Utilities05 Operations And Utilities
05 Operations And Utilities
 
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
12 - gradle. evoliutsiia system avtomatychnoi zbirky - sviatoslav babych - it...
 
cpp-2013 #16 Automated testing
cpp-2013 #16 Automated testingcpp-2013 #16 Automated testing
cpp-2013 #16 Automated testing
 
Clean code (UA)
Clean code (UA)Clean code (UA)
Clean code (UA)
 
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...07 -  vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
07 - vysnovky z tdd, pohliad pochatkivtsia - vitalii zinchenko it event 2013...
 
cpp-2013 #20 Best practices
cpp-2013 #20 Best practicescpp-2013 #20 Best practices
cpp-2013 #20 Best practices
 
Theme22-OOP
Theme22-OOPTheme22-OOP
Theme22-OOP
 
02 Copying Objects
02 Copying Objects02 Copying Objects
02 Copying Objects
 
Automated testing
Automated testingAutomated testing
Automated testing
 
Oop - TTm
Oop - TTmOop - TTm
Oop - TTm
 
ASP.Net MVC
ASP.Net MVCASP.Net MVC
ASP.Net MVC
 
11 Iterated Containers
11 Iterated Containers11 Iterated Containers
11 Iterated Containers
 
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5
Prometheus. Масовий онлайн курс "Основи програмування". Лекція 5
 
Coding for Future in Lutsk. JavaScript. Part 11
Coding for Future in Lutsk. JavaScript. Part 11Coding for Future in Lutsk. JavaScript. Part 11
Coding for Future in Lutsk. JavaScript. Part 11
 
Advanced C#. Part 2
Advanced C#. Part 2Advanced C#. Part 2
Advanced C#. Part 2
 
Функції в C++
Функції в C++Функції в C++
Функції в C++
 

Phpunit модульне тестування

  • 1. PhpUnit модульне тестування Короткий опис модульного тестування з використанням фреймворка PhpUnit
  • 2. 1. Типи тестів: • Модульні тести (юніт тести) Тести найменших одиниць функціональності (модулів). Перевірка, чи функція, яка тестується виконує саме те, для чого вона реалізована. • Інтеграційні тести Поєднує різні одиниці коду (різні модулі). Перевірка чи правильно працює їхня комбінація. • Системні тести • Прийомочні тести
  • 4. 3. Приклад модульного теста use path/Default.php // підключення файла для тесту class defaultTests extends PHPUnit_Framework_TestCase { private $default; protected function setUp() // метод, який викликається перед кожним тестом (незалежно від кількості) { $this->default = new Default(); } protected function tearDown() // метод, який викликається після кожного теста (незалежно від кількості) { $this-> default = NULL; } public function testAdd() // метод тест для метода add() класса Default() { $result = $this->default->add(1, 2); $this->assertEquals(3, $result); //перевірка чи метод повернув правильний результат } }
  • 5. 4. Запуск і результат тесту: phpunit tests/DefaultTest.php PHPUnit 3.7.32 by Sebastian Bergmann. . Time: 31ms, Memory: 2.25Mb OK (1 test, 1 assertion)
  • 6. 5. Використання різних наборів вхідних данних Без використання DataProvider public function testAdd() { $result = $this->calculator->add(1, 2); $this->assertEquals(3, $result); } public function testAddWithZero() { $result = $this->calculator->add(0, 0); $this->assertEquals(0, $result); } public function testAddWithNegative() { $result = $this->calculator->add(-1, -1); $this->assertEquals(-2, $result); }
  • 7. 6. Використання різних наборів вхідних данних Метод, який являється DataProvider’ом, має повертати масив масивів. Метод, який являється тестом буде викликатись декілька раз з кожним масивом, в якості аргументів будуть передаватись вміст масиви. Ключові моменти для використання dataProvider: - метод dataProvider має бути публічним. - метод dataProvider має повертати масив зібраних данних - метод теcта має використовувати аннотоацію @dataProvider, щоб вказати, який метод має використовуватись в якості dataProvider
  • 8. 7. Використання DataProvider public function addDataProvider() { return array( array(1,2,3), array(0,0,0), array(-1,-1,-2), ); } /** * @dataProvider addDataProvider */ public function testAdd($a, $b, $expected) { $result = $this->calculator->add($a, $b); $this->assertEquals($expected, $result); }
  • 9. 8. Asserts assertEquals(‘foo’, ‘foo’) assertTrue(!empty($result)) assertFalse(!empty($result)) assertArrayHasKey('foo', ['bar' => 'baz']) assertClassHasAttribute('foo', stdClass::class) assertContains(4, [1, 2, 3]); assertCount(0, ['foo']) assertDirectoryExists('/path/to/directory') assertDirectoryIsReadable('/path/to/directory') assertFileExists('/path/to/file') assertNull('foo') assertRegExp('/foo/', 'bar') https://phpunit.de/manual/current/en/appendixes.assertions.html
  • 10. 9. Mock Іноді при тестуванні нам потрібно використовувати обєкти, поведінку яких ми не можемо контролювати. Для рішення цієї проблеми можна використовувати mock-обєкти. Наприклад нам потрібно працювати з базою данних. Наприклад є метод який робить важкий запрос в базу данних, який виконується не часто і для нашого тесту не потрібно відтворювати сам запрос, але результат запросу потрібен. Метод getMock створює mock-обєкт з таким самим набором методів, як і звичайний обєкт классу Database. Всі методи, за замовченням, будуть повертати null, але ми можемо перегрузити потрібний нам метод.
  • 11. 9.1. Приклад використання Mock-обєкта class Database { /** * повільний метод який буде викоритсаний */ public function reallyLongTime() { $results = array( array(1, 'test', 'foo value') ); sleep(1000); return $results; } } Class DatabaseTest extends PHPUnit_Framework_TestCase { private $db = null; public function setUp() { $this->db = new Database(); } public function tearDown() { unset($this->db); } public function testReallyLongReturn() { $mock = $this->getMock('Database'); $result = array( array(1, 'foo', 'bar test') ); $mock->expects($this->any()) ->method('reallyLongTime') ->will($this->returnValue($result)); $return = $mock->reallyLongTime(); $this→assertTrue(count($result) == 3); } }  При кожному виклику метода reallyLongTime обєкта $mock буде повертатись значення змінної $result, замість реального виконання методу.
  • 12. 9.2 MockBuilder При роботі з MockBuilder першим методом в ланцюгу викликів має бути getMockBuilder(), а останнім — getMock(). Наприклад, в наступному прикладі ми створюємо mock-обєкт, которий не використовує конструктор, а також вимикає autoload: function testReallyLongRunBuilder() { $stub = $this->getMockBuilder('Database') ->setMethods(array( 'reallyLongTime' )) ->disableAutoload() ->disableOriginalConstructor() ->getMock(); $result = array(array(1, 'foo', 'bar test')); $stub->expects($this->any()) ->method('reallyLongTime') ->will($this->returnValue($result)); $this->assertGreaterThan(0, count($return)); }
  • 13. public function getMock( $originalClassName, // назва оригінального класса, для якого буде створений Mock обєкт $methods = array(), // Массив методів для заміни, якщо вказати null методи будуть без підміни array $arguments = array(), // аргументи, які передаються в конструктор $mockClassName = '', // можна вказати імя Mock класа $callOriginalConstructor = true, // відключити __construct() $callOriginalClone = true, // відключити __clone() $callAutoload = true // відключити __autoload() ); $mock = $this->getMockBuilder('MyClass') ->setMethods(null) ->setConstructorArgs(array()) ->setMockClassName('') ->disableOriginalConstructor() ->disableOriginalClone() ->disableAutoload() ->getMock(); Послідовність методів починається з метода getMockBuilder() и закінчується методом getMock() — ці методи обовязкові.
  • 14. 9.3. Очікування виклику методів PHPUnit дозволяє нам контролювати кількість і порядок викликів підмінених методів. Для цього використовується конструкція expects() з вказуванням потрібного метода за допомогою - method().  public function test_process() {  $mock = $this->getMock('MyClass', array('getTemperature', 'getWord', 'showWord'));  $mock->expects($this->once())->method('getTemperature');  $mock->expects($this->once())->method('showWord');  $mock->expects($this->once())->method('getWord');  $mock->process();  }   Результат виконання этого теста будет успешным, если при вызове метода process() произойдет однократный вызов трех перечисленных методов: getTemperature(), getWord(), showWord(). Обратите внимание, что в тесте проверка вызова getWord() стоит после проверки вызова showWord(), хотя в тестируемом методе наоборот. Все верно, ошибки здесь нет. Для контроля порядка вызова методов в PHPUnit используется другая конструкция — at(). Поправим немного код нашего теста так чтобы PHPUnit проверил заодно очередность вызова методов:  public function test_process() {  $mock = $this->getMock('MyClass', array('getTemperature', 'getWord', 'showWord'));  $mock->expects($this->at(0))->method('getTemperature');  $mock->expects($this->at(2))->method('showWord');  $mock->expects($this->at(1))->method('getWord');  $mock->process();  }   Помимо упомянутых once() и at() для тестирования ожиданий вызовов в PHPUnit есть также следующие конструкции: any(), never(), atLeastOnce() и exactly($count). Их названия говорят сами за себя.