Tôi cần tạo trình nạp tự động cho ứng dụng của mình. Tôi không muốn phụ thuộc vào một tập tin trong hệ thống tập tin, vì vậy làm thế nào để tôi thử một cuộc gọi mới? Hoặc làm thế nào để bạn kiểm tra một lớp autoloader? Cảm ơn.PHPUnit - kiểm tra autoloader lớp
Trả lời
Tạo một số tệp lớp cụ thể để kiểm tra trình nạp tự động của bạn và đặt chúng trong một thư mục riêng biệt (anh chị em với bài kiểm tra) mà bạn có thể đăng ký với trình nạp tự động. Sử dụng class_exists($class, false)
để kiểm tra xem một lớp có được tải không cần gọi trình nạp tự động không.
Lưu ý: Sẽ giúp ích nếu bạn thiết kế trình nạp tự động không tĩnh để có thể khởi tạo một cá thể riêng biệt cho bài kiểm tra thay vì kiểm tra hoạt động.
Dưới đây là các bài kiểm tra đối với phương pháp autoload()
của autoloader tùy chỉnh của tôi làm ví dụ:
function test_autoload_loadsExistingClass() {
$this->fixture->registerPrefix('TestClasses', self::$root . 'models');
if (class_exists('TestClasses_Autoloader_Foo', false)) {
self::error('Class TestClasses_Autoloader_Foo is already loaded');
}
$this->fixture->autoload('TestClasses_Autoloader_Foo');
if (!class_exists('TestClasses_Autoloader_Foo', false)) {
self::fail('Class TestClasses_Autoloader_Foo failed to load');
}
}
function test_autoload_silentlyIgnoresMissingClasses() {
$this->fixture->registerPrefix('Foo', self::$root . 'models');
$this->fixture->autoload('Foo_Bar');
}
function test_autoload_searchesIncludePathForUnknownPrefix() {
if (class_exists('TestClasses_Autoloader_Foo', false)) {
self::error('Class TestClasses_Autoloader_Foo is already loaded');
}
set_include_path(self::$root . 'include' . PATH_SEPARATOR . self::$savedIncludePath);
$this->fixture->autoload('TestClasses_Autoloader_Foo');
if (!class_exists('TestClasses_Autoloader_Foo', false)) {
self::fail('Class TestClasses_Autoloader_Foo failed to load');
}
}
Cập nhật: Wow, tôi không biết làm thế nào tôi đã bỏ lỡ "Tôi không muốn phụ thuộc vào một tập tin trong hệ thống tập tin "trong câu hỏi của bạn, nhưng đó là khá quan trọng. Bạn cần phải thực hiện cuộc gọi đến include
theo phương pháp tự động tải của riêng mình (ví dụ: includeFile($path)
). Điều này sẽ cho phép bạn giả lập phương thức trong khi thử nghiệm để bạn không liên quan đến các tệp trên đĩa. Ngoài ra bạn sẽ kiểm tra lớp như bạn thường làm: nạp các đầu vào (như trên) của các lớp được tự động tải và xác nhận rằng lớp của bạn gọi includeFile()
với đường dẫn chính xác khi cần.
function testAutoloadLoadsExistingClass() {
$fixture = $this->getMock('MyAutoloader',
array('includeFile'), // mock the call to `include`
array(...)); // constructor args
$fixture->expects($this->once())
->method('includeFile')
->with('My/Package/Class')
->will($this->returnValue(true));
self::assertTrue($fixture->autoload('My_Package_Class'));
}
Hoặc làm thế nào để bạn kiểm tra một lớp autoloader
IMHO bạn không cần phải kiểm tra đơn vị autoloader của bạn cả.
Nếu bạn khởi động lại ứng dụng của bạn nó sẽ sụp đổ ether thực sự khó khăn vì nó có thể tìm thấy tất cả các lớp học cần thiết hoặc autoloader của bạn hoạt động tốt.
Mỗi lần kiểm tra trong bộ thử nghiệm của bạn sẽ kiểm tra xem trình nạp tự động có thể tải "lớp đang kiểm tra" không, vì vậy tôi sẽ không lo lắng nhiều về việc kiểm thử đơn vị đó.
Có thể gọi nó là "thử nghiệm tích hợp như là một tác dụng phụ" nếu bạn muốn nhưng tôi muốn nói điều đó là đủ tốt.
Nếu bạn không nghĩ điều đó đủ tốt, tôi đặt câu lệnh yêu cầu/bao gồm trong một chức năng được bảo vệ và ghi đè hàm đó trong trình kiểm tra tự động kiểm tra và kiểm tra xem nó có nhận được giá trị phù hợp hay không.
làm cách nào để bạn kiểm tra lớp tự động tải?
Phụ thuộc vào những gì lớp tự động tải. Ví dụ bạn có thể kiểm tra nếu đăng ký gọi lại tự động tải đã làm việc với spl_autoload_register
.
Hoặc nếu trình nạp tự động của bạn cung cấp chức năng LoadLibrary
tải tất cả các lớp và giao diện của thư viện của bạn, để kiểm tra xem tất cả các lớp đã được tải chưa. Nhưng điều này thường phụ thuộc vào hệ thống tập tin (mà tôi nghĩ là okay).
+1 cho "Kiểm tra tích hợp dưới dạng tác dụng phụ". Tôi thích nó. – GordonM