所有测试都因PHP致命错误而失败:无法重新声明课程

时间:2015-05-23 14:52:01

标签: php phpunit

我在使用PHPUnit时遇到了一个奇怪的行为,我无法判断我是在做错了什么,或者它是否是测试框架中的错误。这是我的情况:

我的项目有几个类:BsInput,BsEmail,BsHidden,BsNumber。 BsEmail,BsHidden和BsNumber扩展了BsInput。所有类都有单元测试类(BsInputTest用于BsInput,BsEmailTest用于BsEmail等)。

单独执行的每个单元测试都很顺利。

现在,如果我尝试在我的项目中运行所有测试,我会收到错误消息“PHP致命错误:无法在第80行的/some/path/to/B.php中重新声明B类”。

以下是每个文件的内容:

BsInput.php

require_once __DIR__ . "/BsInputControl.php";

class BsInput extends BsInputControl {
    ...
}

BsEmail.php

require_once __DIR__ . "/BsInput.php";

class BsEmail extends BsInput {
    ...
}

BsHidden.php

require_once __DIR__ . "/BsInput.php";

class BsHidden extends BsInput {
    ...
}

BsNumber.php

require_once __DIR__ . "/BsInput.php";

class BsNumber extends BsInput {
    ...
}

BsInputTest.php

require_once "../colibri/bs/BsInput.php";

class BsInputTest extends PHPUnit_Framework_TestCase {
    ...
}

BsEmailTest.php

require_once "../colibri/bs/BsEmail.php";

class BsEmailTest extends PHPUnit_Framework_TestCase {
    ...
}

BsHiddenTest.php

require_once "../colibri/bs/BsHidden.php";

class BsHiddenTest extends PHPUnit_Framework_TestCase {
    ...
}

BsNumberTest.php

require_once "../colibri/bs/BsNumber.php";

class BsNumberTest extends PHPUnit_Framework_TestCase {
    ...
}

现在最后一件让我疯狂的小事:如果我在BsHidden.php和BsHiddenTest.php中注释掉所有代码,那么PHPUnit All Tests执行在BsNumber和后续课程中顺利进行!

有没有人见过类似的东西?有什么线索我应该看看我的问题解决了吗?

我尝试过一种丑陋的解决方法:在BsInput.php中插入以下代码

var_dump(class_exists('BsInput', FALSE));
if (class_exists('BsInput', FALSE)) { return; }

我得到了这个结果:

bool(true)
PHP Fatal error: Cannot redeclare class BsInput in /.../BsInput.php on line 87

到目前为止,我已经看过许多问题,包括上述问题,但到目前为止我找不到任何解决方案。

我也尝试将PHPUnit更新到最新版本(4.6),但没有成功。

我的平台是: Mac OS X 10.10 PHP 5.5.20 PHPUnit 4.6.6 Netbeans 8.0.2(如果这有任何相关的内容)

有人知道吗?

在尝试解决这个问题后,我终于删除了我的BsHidden.php文件,附带的测试文件并完全重新创建了它们(我的意思是我复制/粘贴完全相同的内容)......现在它可以了!这真的让我想到PHP和PHPUnit之间的某个错误。

然而快速&肮脏的解决方法似乎是:

  1. 将文件和单元测试文件内容复制粘贴到另一个文件
  2. 删除有问题的文件和单元测试文件(如果有)
  3. 重新创建文件和单元测试文件并粘贴内容

2 个答案:

答案 0 :(得分:3)

我终于确定了我的问题。似乎有一个PHP错误,至少在我的平台上。

PHP的手册说(http://php.net/manual/en/function.include-once.php)PHP4中的名称解析对不区分大小写的系统不区分大小写,而PHP5则处理这些问题。

以下是我在平台上的行为(Mac OS X 10.10,PHP 5.5):

假设我有一个文件var app =angular.module('dashboard',['ui.bootstrap']); app.controller('dashboardController', function($scope, $http,$modal ){ $scope.objects=[{}]; $scope.objects={}; $scope.objects=[]; $scope.grupos =[{}]; $scope.longitud =[{}]; $scope.eventos =[{}]; var URLEvents = "/api/events/"; //Abrimos modal y les pasamos los eventos de esa instalación $scope.open = function (object) { $http.get(URLEvents + object.liftsiteid, $scope) .success(function (data) { var events = data; angular.forEach(events, function(event) { $scope.eventos = event; var modalInstance = $modal.open({ templateUrl: 'myModalContent.html', controller: 'ModalInstanceCtrl', size: 'lg', resolve: { items: function () { return $scope.eventos; } } }); }) }) .error(function (data) { window.alert('Something Wrong...'); }); }; var URLOperation ="/api/sites"; //Funci?n que devuelve las instalaciones de un usuario $http.get(URLOperation, $scope) .success(function(data) { var groups = data; angular.forEach(groups, function(group) { var group2 = group; angular.forEach(group2.sites, function(group3){ $scope.longitud.push(group3); $scope.objects.push(group3); $scope.predicate = 'msisdn'; $scope.reverse = true; $scope.order = function(predicate) { $scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false; $scope.predicate = predicate; }; }) }); }) .error(function(data) { window.alert('Something Wrong...'); }); }); //Abrimos el modal y le enviamos los eventos app.controller('ModalInstanceCtrl', function ($scope, $modalInstance, items, $anchorScroll){ $anchorScroll(); $scope.eventos =[{}]; $scope.eventos.push(items); $scope.cancel = function () { $modalInstance.dismiss('cancel'); }; }); ,它定义了一个A.php类和以下代码:

A

第二个<?php require_once 'A.php'; require_once 'a.php'; ?> 触发require_once。因此,在Mac OS X上的PHP5.5中,至少名称解析不区分大小写,但是PHP仍然认为它们是不同的文件

答案 1 :(得分:0)

您只是使用class_exists,请按照以下方式使用:

if (!class_exists('BsInput', FALSE)) { 
    class BsInput extends BsInputControl {
        // ToDo
    }
}

我不知道为什么会生成此错误 - 您是否无处不在无处不在 require_