以下代码将使PHP不高兴,customMethod()是私有的.为什么会这样?可见性是由声明某事物而非定义的地方决定的吗?
如果我想使customMethod仅对Template类中的样板代码可见并防止它被覆盖,那么我是否会将其保护并最终?
的template.php:
abstract class Template() {
abstract private function customMethod();
public function commonMethod() {
$this->customMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
CustomA.php:
class CustomA extends Template {
private function customMethod() {
blah...
}
}
Run Code Online (Sandbox Code Playgroud)
Main.php
...
$object = new CustomA();
$object->commonMethod();
..
Run Code Online (Sandbox Code Playgroud) 如何在PHPUnit中存根一个由test的构造函数中的类调用的方法?例如,下面的简单代码将无法工作,因为在我声明存根方法时,已经创建了存根对象,并且我的方法被调用,取消存储.
要测试的类:
class ClassA {
private $dog;
private $formatted;
public function __construct($param1) {
$this->dog = $param1;
$this->getResultFromRemoteServer();
}
// Would normally be private, made public for stubbing
public getResultFromRemoteServer() {
$this->formatted = file_get_contents('http://whatever.com/index.php?'.$this->dog);
}
public getFormatted() {
return ("The dog is a ".$this->formatted);
}
}
Run Code Online (Sandbox Code Playgroud)
测试代码:
class ClassATest extends PHPUnit_Framework_TestCase {
public function testPoodle() {
$stub = $this->getMockBuilder('ClassA')
->setMethods(array('getResultFromRemoteServer'))
->setConstructorArgs(array('dog52'))
->getMock();
$stub->expects($this->any())
->method('getResultFromRemoteServer')
->will($this->returnValue('Poodle'));
$expected = 'This dog is a Poodle';
$actual = $stub->getFormatted();
$this->assertEquals($expected, $actual);
}
}
Run Code Online (Sandbox Code Playgroud) 我在PHPUnit中看到的下一个奇怪之处:
class DummyTest extends PHPUnit_Framework_TestCase {
public function testDummy() {
$this->assertTrue(false, 'assert1');
$this->assertTrue(false, 'assert2');
}
public function testDummy2() {
$this->assertTrue(false, 'assert3');
}
}
Run Code Online (Sandbox Code Playgroud)
一旦第一个断言在测试中失败,则忽略测试的其余部分.
所以(通过简单调用phpunit DummyTest.php):
上面的代码将显示2个测试, 2个断言,2个失败.什么?
如果我通过所有测试,那么我会好的(2个测试,3个断言).好.
如果我只通过除assert2之外的所有测试,我得到2个测试,3个断言,1个失败.好.
我不明白,但是PHPUnit已经存在了很长时间,当然它必须是我吗?
计数不仅不是我期望的,而且只显示上面代码中第一个失败断言的错误消息.
(顺便说一句,我正在分析PHPUnit为CI生成的xml格式,而不是测试实际代码,因此在一次测试中实现了多个断言.)
我的真实场景有点难以解释,因此我将它映射到一个更易识别的领域,比如家庭娱乐设备:
特定设备可以提供不同的服务:
Panasonic XYZ可以播放DVD和CD.
索尼ABC只能播放CD.
Hitachi PQR可以播放DVD并接收电视.
...
...
每项服务(DVD,CD,TV,......)都有一个大多数模型使用的默认实现,但某些模型具有特定服务的定制版本.
接口
选择实现DVD',CD',TV'izable,...合同的模型将导致模型之间的大量代码重复.
单一继承
实现默认服务的单个超类允许我为每个模型包含一个包含其所有自定义行为的子类.然而,对于不提供所有类型服务的模型,我的超类将非常笨重且比它需要的更重.
多重继承
在表面上具有选择性地整合所需服务并提供默认实现的能力的多重继承似乎是理想的.我重视将所有PanasonicXYZ的自定义功能集中在一个类中的内聚性,而不是继承所引入的耦合.
但我不是在使用C++(而是使用PHP),我觉得有一种更好的方法.我也不想使用mixins或5.4的特性等专有扩展.
组成
我看到一个类爆炸,我的自定义功能分散在多个类的特定模型上 - 例如,我需要PanasonicXYZ_CD类和PanasonicXYZ_DVD类,它们只能被PanasonicXYZ对象使用.
有更好的结构吗?
编辑:我会很好地思考一些评论和答案,而不是过早评论.
当PHPUnit断言失败时,我不需要下面的堆栈跟踪,只是我的自定义消息("Type: R Expected: 333.33333333333 Actual: 345")和PHPUnit的失败消息("Failed assert that false is true").
除了将所有测试放在try/catch块中并在显示之前从异常消息中剥离堆栈跟踪之外,还有其他方法吗?
我不希望堆栈跟踪消除除PHPUnit_Framework_ExpectationFailedException之外的任何异常,但是如果这不可能,我可以处理在所有PHPUnit测试期间丢失堆栈跟踪.
SO上的其他帖子似乎提出了相反问题的解决方案,当xdebug将其关闭时,将堆栈跟踪恢复.
PHPUnit_Framework_ExpectationFailedException : Type: R Expected: 333.33333333333 Actual: 345
Failed asserting that false is true.
#0 /usr/share/php/PHPUnit/Framework/Constraint.php(91): PHPUnit_Framework_Constraint->fail(false, 'Type: R Expecte...')
#1 /usr/share/php/PHPUnit/Framework/Assert.php(2134): PHPUnit_Framework_Constraint->evaluate(false, 'Type: R Expecte...')
#2 /usr/share/php/PHPUnit/Framework/Assert.php(888): PHPUnit_Framework_Assert::assertThat(false, Object(PHPUnit_Framework_Constraint_IsTrue), 'Type: R Expecte...')
#3 /home/simon/Development/golfants/website/unit_tests/PostTest.php(33): PHPUnit_Framework_Assert::assertTrue(false, 'Type: R Expecte...')
#4 [internal function]: PostTest->testRandomAntTypeSelected()
#5 /usr/share/php/PHPUnit/Framework/TestCase.php(976): ReflectionMethod->invokeArgs(Object(PostTest), Array)
#6 /usr/share/php/PHPUnit/Framework/TestCase.php(831): PHPUnit_Framework_TestCase->runTest()
#7 /usr/share/php/PHPUnit/Framework/TestResult.php(648): PHPUnit_Framework_TestCase->runBare()
#8 /usr/share/php/PHPUnit/Framework/TestCase.php(776): PHPUnit_Framework_TestResult->run(Object(PostTest))
#9 /usr/share/php/PHPUnit/Framework/TestSuite.php(775): PHPUnit_Framework_TestCase->run(Object(PHPUnit_Framework_TestResult))
#10 /usr/share/php/PHPUnit/Framework/TestSuite.php(745): PHPUnit_Framework_TestSuite->runTest(Object(PostTest), …Run Code Online (Sandbox Code Playgroud) 我注意到当我使用模拟对象时,PHPUnit将正确报告执行的测试数量但错误地报告我正在进行的断言数量.事实上,每次我嘲笑它都算作另一个断言.一个包含6个测试的测试文件,7个断言语句和每个测试模拟一次报告6个测试,13个断言.
这是除了一个测试以外的所有测试的测试文件(这里用于说明),另外我介绍了另一个不存根以追踪此问题的测试.PHPUnit报告了2个测试,3个断言.我删除了dummy:1 test,2个断言.
require_once '..\src\AntProxy.php';
class AntProxyTest extends PHPUnit_Framework_TestCase {
const sample_client_id = '495d179b94879240799f69e9fc868234';
const timezone = 'Australia/Sydney';
const stubbed_ant = "stubbed ant";
const date_format = "Y";
public function testBlankCategoryIfNoCacheExists() {
$cat = '';
$cache_filename = $cat.'.xml';
if (file_exists($cache_filename))
unlink($cache_filename);
$stub = $this->stub_Freshant($cat);
$expected_output = self::stubbed_ant;
$actual_output = $stub->getant();
$this->assertEquals($expected_output, $actual_output);
}
public function testDummyWithoutStubbing() {
$nostub = new AntProxy(self::sample_client_id, '', self::timezone, self::date_format);
$this->assertTrue(true);
}
private function stub_FreshAnt($cat) {
$stub = $this->getMockBuilder('AntProxy')
->setMethods(array('getFreshAnt'))
->setConstructorArgs(array(self::sample_client_id, $cat, self::timezone, self::date_format))
->getMock();
$stub->expects($this->any())
->method('getFreshAnt') …Run Code Online (Sandbox Code Playgroud) 因此,例如,如果光标在一行的中间,按下SHIFT两次向下箭头将选择三整行,而不是从当前光标位置到下面 2 行的相同位置。
返回的matchs数组包含匹配的整个字符串作为第一个元素,然后是捕获的组。
我找不到php.net上的选项以仅返回捕获的组?
有一个吗?
我无法正确地为派生表别名设置语法:
SELECT * FROM
(SELECT a.*, b.*
FROM a INNER JOIN b ON a.B_id = b.B_id
WHERE a.flag IS NULL AND b.date < NOW()
UNION
SELECT a.*, b.*
FROM a INNER JOIN b ON a.B_id = b.B_id
INNER JOIN c ON a.C_id = c.C_id
WHERE a.flag IS NOT NULL AND c.date < NOW())
AS t1
ORDER BY RAND() LIMIT 1
Run Code Online (Sandbox Code Playgroud)
我得到一个重复的列名B_id.有什么建议?
我已经尝试过7-8个UML程序,从简单到相当复杂,我还没有找到我爱上的单个软件.
Gliffy最接近正确的轨道.它的功能有限,这意味着什么都不会妨碍绘画.它可以与我的问题跟踪器和Wiki集成,这很棒.但是它缺少活动和状态图的符号.加上它的连接过程有点笨拙.
所以我也在使用MagicDraw.通过其连接模式可以非常快速地绘制图表.然而,该程序对我的使用来说太过分了.我只想输入<<cat>>一个类框,而不是首先在UML配置文件中将其定义为新的构造型等等.此外,程序需要永远加载,保存等.
Autodesk Sketchbook和图形输入板几乎已经足够好了,我将它用作我的白板,用于很多事情.快速,但是当然凌乱,并且在基于矢量的抽屉中移动符号和保持连接的速度要快得多.
因此,我继续搜索UML图表软件,该软件说敏捷开发人员通常会使用它来快速绘制草图,而不必与该工具进行战斗或减速.没有逆向工程或代码生成业务,没有"智能"功能将您锁定为标准UML.我知道要画什么,我只想要一个足够的工具包来加快速度.
Visio我在5分钟内没有喜欢,与ArgoUML和Dusan以及其他一些我试过的东西相同?
任何人都可以使用一些不会妨碍他们学习它的怪癖的东西吗?
编辑:Windows平台.
如果问题是愚蠢的,请原谅,我只是第二天在Ant上和Java一起攻击一些CI解决方案,而不知道Ant或Java.
所以我希望构建失败如果(我的)java程序作为构建中的一个步骤运行,则决定构建必须失败.
我想过只是在Java程序中抛出一个未处理的异常,或者使用System.exit()来关闭JVM,但它们看起来非常讨厌.
如果一个java步骤决定它应该有一个很好的方式蚂蚁失败的构建?
两个表 A 和 B,A 记录包含对 B 记录的引用。
我在 B 中有一些 A 没有使用的记录。
只需在一条 SQL 语句之后删除它们。
php ×6
phpunit ×4
java ×2
sql ×2
abstraction ×1
agile ×1
ant ×1
foreign-keys ×1
inheritance ×1
oop ×1
preg-match ×1
regex ×1
uml ×1
union ×1