2012-02-03 2 views
10

Tôi có một bài kiểm tra đơn vị không thành công vì các tiêu đề đã được gửi đi. Tuy nhiên, tiêu đề trong trường hợp này được mong đợi.Làm cách nào để kiểm tra các tiêu đề dự kiến?

Làm cách nào để yêu cầu PHPUnit mong đợi tiêu đề 500?

Tôi đã đọc this question nhưng không hiệu quả.

Phương pháp được bọc bên trong bộ đệm đầu ra.

ob_start(); 
$foo->methodWhichSendsHeader(); 
ob_clean(); 
+1

Bạn có chắc chắn rằng [câu trả lời này] (http://stackoverflow.com/a/190498/212940) không chính xác cho trường hợp của bạn không? – vascowhite

Trả lời

19

Nếu bạn đã cài đặt xdebug, bạn có thể sử dụng xdebug_get_headers() để lấy tiêu đề. Sau đó, bạn có thể kiểm tra chúng khi cần thiết.

$headers=xdebug_get_headers(); 

giúp bạn một mảng mà trông giống như ...

array(
    0 => "Content-type: text/html", 
    1 => ... 
) 

Vì vậy, bạn sẽ cần phải phân tích mỗi dòng tiêu đề để tách các tên tiêu đề từ giá trị

+0

Điều này hoạt động tốt cho các cuộc gọi có định dạng 'tiêu đề ('Content-Type: text/html'); ' nhưng dường như không hoạt động đối với các cuộc gọi định dạng ' header (' HTTP/1.1 500 Internal Server Lỗi ');' có cách nào để lấy các tiêu đề/mã trạng thái này không? – Derokorian

+0

Mặc dù bạn không thể nhận được nội dung tiêu đề thực tế từ 'header ('HTTP/1.1 500 Internal Server Error');', bạn * có thể * sử dụng [http_response_code()] được xây dựng sẵn (http://php.net) /manual/en/function.http-response-code.php) để truy xuất mã trạng thái HTTP sẽ được trả về trình duyệt. – JSmitty

2

Nếu bạn có thể' t sử dụng xdebug_get_headers trên hệ thống của bạn, cách tiếp cận khác là giả lập chức năng tiêu đề.

Tôi đang sử dụng các tính năng sau đây, hoạt động tuyệt vời. Cho phép nói rằng bạn có mã này ...

<?php 
header('Content-type: text/plain; charset=UTF-8'); 
... 

tôi thay header với một chức năng tiêu đề đó là kiểm chứng như thế này ...

<?php 
Testable::header('Content-type: text/plain; charset=UTF-8'); 
... 

Lớp Testable được thực hiện như sau. Lưu ý rằng các chức năng chỉ cần được thêm vào trước với Testable::. Nếu không, chúng hoạt động giống như các chức năng thông thường.

class Testable { 
    private static $headers=array(); 

    static function header($header) { 
     if (defined('UNIT_TESTING')) { 
     self::$headers[]=$header; 
     } else { 
     header($header); 
     } 
    } 

    public static function reset() { 
     self::$headers=array(); 
    } 

    public static function headers_list() { 
     if (defined('UNIT_TESTING')) { 
      return self::$headers; 
     } else { 
      return headers_list(); 
     } 
    } 
} 

Bây giờ tất cả những gì bạn cần làm là xác định UNIT_TESTING trong các thử nghiệm của mình, nhưng không phải trong quá trình sản xuất. Sau đó, khi bạn đến để kiểm tra tiêu đề của bạn, chỉ cần gọi Testable::headers_list().

Tất nhiên, bạn nên thêm các phương thức cho setcookie, headers_sent và bất kỳ chức năng nào khác phát hành tiêu đề HTTP.

+4

Đúng nhưng điều này sửa đổi đối tượng thử nghiệm. Điều đó không tốt. –

+0

@JimmyKane - Không hơn bất kỳ mô hình nào, theo như tôi có thể nói. Bạn có thể để lời gọi đến tiêu đề Testable :: trong mã sản xuất, miễn là trong quá trình sản xuất UNIT_TESTING không được xác định. Có cái gì tôi đang thiếu ở đây? –

+1

Điều tôi muốn nói là bạn phải thêm một hàm tĩnh vào lớp của bạn và do đó sửa đổi lớp 'Testable'. Tôi không muốn chỉnh sửa và thêm phần tử tĩnh này vào mọi bản tóm tắt gửi tiêu đề để có thể kiểm tra. Nhưng đó chỉ là một sở thích. Khác hơn là câu trả lời của bạn là tốt. Có một ngày tuyệt vời. –