2014-12-16 20 views
5

Próbuję przetestować metody z poniższej klasie mam napisane (istnieje więcej funkcji niż to, co jest pokazane w zasadzie jedna funkcja dla każdego jest _ *() metoda):Jak PHPUnit przetestować metodę bez wartości zwracanej?

class Validate { 
    private static $initialized = false; 

    /** 
    * Construct won't be called inside this class and is uncallable from the outside. This prevents 
    * instantiating this class. This is by purpose, because we want a static class. 
    */ 
    private function __construct() {} 

    /** 
    * If needed, allows the class to initialize itself 
    */ 
    private static function initialize() 
    { 
    if(self::$initialized) { 
     return; 
    } else { 
     self::$initialized = true; 
     //Set any other class static variables here 
    } 
    } 

    ... 

    public static function isString($string) { 
    self::initialize(); 
    if(!is_string($string)) throw new InvalidArgumentException('Expected a string but found ' . gettype($string)); 
    } 

    ... 

} 

Kiedy sprawdzić, czy metody rzucają wyjątek na nieprawidłowe dane wejściowe, działa świetnie! Jednak kiedy testuję, czy metoda działa zgodnie z oczekiwaniami, PHPUnit narzeka, ponieważ nie mam dowodu w teście. Specyficzny błędu:

# RISKY This test did not perform any assertions 

Jednak nie mam żadnej wartości do dochodzenia przed więc nie jestem pewien, jak przezwyciężyć.

Czytałem trochę o testowaniu metod statycznych, ale w większości przypadków wydaje się, że obejmują one zależności między metodami statycznymi. Co więcej, nawet metody niestatyczne mogą nie mieć wartości zwracanej, więc jak to naprawić?

Dla porównania, mój kodu testu:

class ValidateTest extends PHPUnit_Framework_TestCase { 
    /** 
    * @covers ../data/objects/Validate::isString 
    * @expectedException InvalidArgumentException 
    */ 
    public function testIsStringThrowsExceptionArgumentInvalid() { 
    Validate::isString(NULL); 
    } 

    /** 
    * @covers ../data/objects/Validate::isString 
    */ 
    public function testIsStringNoExceptionArgumentValid() { 
    Validate::isString("I am a string."); 
    } 
} 
+2

Dlaczego ta metoda nie zwróci true/false? Czy byłby to wyjątek, gdy wartość inna niż łańcuchowa jest przekazywana jako parametr, ponieważ oczywiście metoda sprawdzania, czy coś jest łańcuchem, powinna oczekiwać wartości nie będących ciągami lub nie ma użyteczności dla tej metody. Wydaje się to nierozsądną metodą. –

+0

@MikeBrant Nie wraca, ponieważ nie ma takiej potrzeby. Używam tej metody w moim kodzie jako break/assert - jeśli metoda nie wyrzuci wyjątku, mój kod będzie działał normalnie. Jeśli tak, wyjątek musi zostać rozwiązany. Nie ma żadnego powodu, aby zwracać cokolwiek z tych metod, a nawet mniej powodów do pisania instrukcji if/else i cykli wydatków sprawdzających te zwracane wartości. Chcę wyjątku zamiast TRUE/FALSE, ponieważ wyjątki mogą zatrzymać wykonywanie kodu. Jeśli wstawisz int, w którym tablica powinna się znaleźć w Javie (lub w większości języków pisanych na klawiaturze), otrzymasz wyjątek. Chcę podobną funkcjonalność. –

+0

@MikeBrant Dalsze, właściwe testowanie oznacza zapewnienie, że moja metoda działa zarówno dla nieprawidłowych, jak i ważnych danych wejściowych. –

Odpowiedz

3

Jedno rozwiązanie Przyszedłem po to następuje, na podstawie example 2.12 from chapter 2 of PHPUnit. Dla mnie to trochę dziwne, ale to najlepsze, co do tej pory znalazłem. Ponadto, na podstawie tego PHPUnit Gitub issue discussion, wydaje się, że kilka innych osób chce tej funkcji, ale nie ma planów jej wdrożenia.

Zmień testIsStringNoExceptionArgumentValid() na następujący:

/** 
    * @covers ../data/objects/Validate::isString 
    */ 
    public function testIsStringNoExceptionArgumentValid() { 
    try { 
     Validate::isString("I am a string."); 
    } catch (InvalidArgumentException $notExpected) { 
     $this->fail(); 
    } 

    $this->assertTrue(TRUE); 
    } 
+1

Nie potrzebujesz bitu try/catch. Nie trzeba awarię(), zrobi to wyjątek. –

+0

Jak przetestować metodę, która nie zwraca niczego i nie rzuca żadnego wyjątku – Somar

2

test funkcji void z assertNull:

/** 
    * @covers ../data/objects/Validate::isString 
    */ 
    public function testIsStringNoExceptionArgumentValid() { 
     $this->assertNull(Validate::isString("I am a string.")); 
    } 
Powiązane problemy