Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHPUnit] Testowanie metody, która ma referencję
wujek2009
post 27.12.2016, 17:29:00
Post #1





Grupa: Zarejestrowani
Postów: 350
Pomógł: 31
Dołączył: 23.05.2010

Ostrzeżenie: (0%)
-----


Hej,

Mam sytuację, w której jest metoda a jeden z jej argumentów idzie przez referencję. Mój problem polega na tym, że ta referencja zwraca IDki, które później są sprawdzane w innej metodzie (tej, która wywołała) czy IDki są w tablicy, jeśli tak to zwróć true. Poniżej przedstawiam schemat (nazwy klas, metod - zmyślone na potrzeby tematu, flow jest jednak ten sam):

  1. <?php
  2.  
  3. class Db
  4. {
  5. public function update($rows, &$success, &$error)
  6. {
  7. if ((..)) {
  8. $success[] = $this->getId();
  9. } else {
  10. $error[] = $this->getId();
  11. }
  12. }
  13. }
  14.  
  15. class Prepare
  16. {
  17. protected $db;
  18.  
  19. public function setDb($db)
  20. {
  21. // itd.
  22. }
  23.  
  24. public function make()
  25. {
  26. // $rows = (...) jakaś tam obróbka danych
  27. $success = array();
  28. $error = array();
  29.  
  30. $this->db->update($rows, $success, $error);
  31.  
  32. return ((count($success) > 0 AND count($error) == 0) ? true : false);
  33. }
  34. }
  35.  
  36. class TestPrepare extends PHPUnit_Framework_TestCas
  37. {
  38. public function testMakeMethod()
  39. {
  40. $mck = Mockery::mock();
  41. $mck->shouldReceive('update')
  42. ->with(
  43. ['id' => 51, 'name' => 'John', 'password' => 'Hour']
  44. // REFERENCE?
  45. // REFERENCE?
  46. )
  47. ->once()
  48. ->andReturn(true)
  49.  
  50. $prepare = new Prepare();
  51. $prepare->setDb($mck);
  52. $response = $prepare->make();
  53.  
  54. $this->assertTrue($response)
  55. }
  56. }


I teraz dla #44, #45 linijki nie wiem co mam wstawić, aby metoda, którą mockuje przekazywała w sobie też referencję z testowymi danymi, próbowałem coś w stylu:
  1. ->with(
  2. ['id' => 51, 'name' => 'John', 'password' => 'Hour']
  3. \Mockery::on(function(&$error) {
  4. $error = array();
  5.  
  6. return true;
  7. }),
  8. \Mockery::on(function(&$success) {
  9. $success[] = 51;
  10.  
  11. return true;
  12. }),
  13. )


ale to nie działa, ponieważ jak zrobię sobie:
  1. var_dump($success, $errors)


przed tym return w klasie: Prepare to cały czas mam pustą tablice - w ogóle nie dodało mojego "51" (jako ID) w konsekwencji mam, że test nie przeszedł. Ma ktoś jakiś pomysł?
Go to the top of the page
+Quote Post
lukaskolista
post 29.12.2016, 15:47:00
Post #2





Grupa: Zarejestrowani
Postów: 872
Pomógł: 94
Dołączył: 31.03.2010

Ostrzeżenie: (0%)
-----


Stworzyłeś idealny przykład na to, dlaczego nie należy używać referencji (nie mówię o obiektach, które mają referencje tworzone przez mechanizm języka).

http://docs.mockery.io/en/latest/reference...behaviours.html
  1. <?php
  2.  
  3. $m->shouldReceive('insert')->with(
  4. \Mockery::on(function(&$data) {
  5. if (!is_array($data)) return false;
  6. $data['_id'] = 123;
  7. return true;
  8. }),
  9. \Mockery::any()
  10. );


Nie znam mockery, ale być może linijka
if (!is_array($data)) return false;
jest jednak istotna (php to bardzo magiczny język z wieloma magicznie działającymi bibliotekami smile.gif).

Ten post edytował lukaskolista 29.12.2016, 15:56:20
Go to the top of the page
+Quote Post
skowron-line
post 30.12.2016, 07:20:47
Post #3





Grupa: Zarejestrowani
Postów: 4 340
Pomógł: 542
Dołączył: 15.01.2006
Skąd: Olsztyn/Warszawa

Ostrzeżenie: (0%)
-----


@wujek2009 teoria jak i praktyka mówi że jeżeli masz problem z przetestowaniem kodu to najprawdopodobniej napisałeś go źle. Na twoim miejscu nie tracił bym czasu na szukanie rozwiązania odnośnie testowania a skupił się na przemyśleniu kodu który napisałeś

  1. class Db
  2. {
  3. public function update($rows, &$success, &$error)
  4. {
  5. if ((..)) {
  6. $this->success[] = $this->getId();
  7. } else {
  8. $this->errored[] = $this->getId();
  9. }
  10. }
  11.  
  12. public function getSuccessfullyProcessed()
  13. {
  14. return $this->success;
  15. }
  16.  
  17. public function getErrored()
  18. {
  19. return $this->errored;
  20. }
  21. }


--------------------
I'm so fast that last night I turned off the light switch in my hotel room and was in bed before the room was dark - Muhammad Ali.
Peg jeżeli chcesz uprawiać sex to dzieci muszą wyjść, a jeżeli chcesz żeby był dobry ty też musisz wyjść - Al Bundy.

QueryBuilder, Mootools.net, bbcradio1::MistaJam
http://www.phpbench.com/
Go to the top of the page
+Quote Post
wujek2009
post 30.12.2016, 19:50:37
Post #4





Grupa: Zarejestrowani
Postów: 350
Pomógł: 31
Dołączył: 23.05.2010

Ostrzeżenie: (0%)
-----


Dzięki Panowie za odpowiedź. Jeśli chodzi o samą prezentację kodu to wygląda to tak, że do istniejącego rozwiązania muszę dopisać testy.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 20.04.2024 - 05:20