2010-11-19 23 views
16

làm cách nào để thay đổi thời gian hiện tại (tức là đầu ra của thời gian()) trong php đối với lớp điều khiển ngày xử lý đơn vị?cách thay đổi thời gian hiện tại cho các chức năng ngày thử nghiệm đơn vị trong php

+0

http://stackoverflow.com/questions/530649/is-it-possible-to-replace-monkeypatch-php-functions –

+0

Bạn có thể hiển thị một số mã không? Theo ý kiến ​​của tôi, nếu bạn cần ghi đè 'time()' để kiểm tra đơn vị, có * có thể là * có vấn đề gì đó với thử nghiệm hoặc mã. – netcoder

+0

lớp thao tác ngày hiện tại. tôi chỉ muốn kiểm tra xem tất cả các phương thức đều chính xác trong tất cả các ngày. – happytoad

Trả lời

3

Âm thanh như bạn cần phải loại bỏ sự phụ thuộc của time() từ lớp thao tác cập nhật của bạn

+0

vì vậy, tôi nên thay đổi logic của lớp học chỉ để thử nghiệm? – happytoad

+1

@happytoad - không bạn chỉ cần thay thế cuộc gọi thành 'time()' trong lớp thao tác ngày của bạn thành thứ bạn kiểm soát. Ví dụ, bạn có thể chuyển một giá trị thời gian cho hàm bạn đang thử nghiệm như một tham số, hoặc, bạn có thể chuyển nó tới hàm tạo của lớp ngày của bạn. – rojoca

+1

để không có cách nào thay đổi thời gian. thật kỳ lạ là điều đơn giản như thay đổi thời gian hiện tại không có sẵn để thử nghiệm. thành thật. cảm ơn. – happytoad

3

tôi đoán là bạn đang phải vật lộn với sự phụ thuộc của bạn. Có vẻ như bạn đang sử dụng hàm time() bên trong lớp của bạn trong khi thử nghiệm đơn vị bạn muốn đảm bảo rằng bạn kiểm soát đầu ra của các phương thức/lớp cung cấp thời gian cho bạn. Tôi muốn nói tạo ra một lớp thời gian cung cấp cho bạn thời gian và giả lập nó vào các bài kiểm tra đơn vị của bạn.

5

Gần đây tôi đã đưa ra một giải pháp tuyệt vời nếu bạn đang sử dụng không gian tên PHP 5.3. Bạn có thể thực hiện một hàm time() mới bên trong vùng tên hiện tại của bạn và tạo một tài nguyên chia sẻ nơi bạn đặt giá trị trả về trong các thử nghiệm của mình. Sau đó, bất kỳ cuộc gọi không đủ tiêu chuẩn nào đến thời gian() sẽ sử dụng chức năng mới của bạn.

Để đọc thêm tôi đã mô tả nó một cách chi tiết trong tôi blog

+1

Gần đây, tôi đã triển khai thư viện [php-mock] (https://github.com/malkusch/php-mock) sử dụng tính năng ngôn ngữ đó để mô phỏng các hàm PHP không xác định như 'time()'. –

3

Bạn có thể xem xét một mô hình thừa kế giao diện dựa trên:

interface iClock 
{ 
    public function getTime(); 

} 

class SystemClock implements iClock 
{ 
    public function getTime() 
    { 
     return time(); 
    } 
} 

class FakeClock implements iClock 
{ 
    private $time; 

    function __construct($time) 
    { 
     $this->time = $time; 
    } 

    public function getTime() 
    { 
     return $this->time; 
    } 

    // you could have more functions to advance the time, etc. 
} 

lớp riêng của bạn mà cần phải làm việc với thời gian hiện tại sẽ mất tham số hàm tạo của loại giao diện iClock.

class YourOwnClass 
{ 
    private $clock; 

    function __construct(iClock $clock) 
    { 
     $this->clock = $clock; 
    } 

    function someFunction() 
    { 
     $now = $this->clock->getTime(); 

     // whatever 
     return $now; 
    } 
} 

Sau đó, bạn chỉ cần tiêm những loại đồng hồ bạn muốn, tùy thuộc vào việc bạn đang trong một thử nghiệm đơn vị hay không:

$realWorldInstance = new YourOwnClass(new SystemClock()); 
echo $realWorldInstance->someFunction(); 
$unitTestInstance = new YourOwnClass(new FakeClock(1234)); 
echo $unitTestInstance->someFunction(); 

BTW - Tôi sử dụng mô hình này thường trong .NET. Nó cũng được tích hợp vào giao diện IClock được cung cấp bởi Noda Time. Tôi thấy không có lý do tại sao mô hình này sẽ không hoạt động trong PHP. Bạn có thể chọn trả lại một DateTime thay vì chỉ dấu thời gian nguyên, nhưng ở trên là số tiền tối thiểu cần thiết để sử dụng mẫu.

Các vấn đề liên quan