我尝试找到问题的解决方案,但没有找到任何结果。
我使用: Symfony,Doctrine,PhpUnit
我有一个实体类InvoiceNumerator:
array(2) {
["www.test.pl"]=>
array(3) {
["category"]=>
array(3) {
}
["category2"]=>
array(3) {
}
}
["www.test2.pl"]=>
array(3) {
["category"]=>
array(3) {
}
["category2"]=>
array(3) {
}
["category3"]=>
array(3) {
}
}
}
我需要在我的测试中模拟这个类,但是我的setter应该保持不变 - 没有存根 - 工作代码。 为了模拟这个类,我做了一个简单的模拟方法:
/**
* InvoiceNumerator
*
* @ORM\Table(name="invoice_numerator")
* @ORM\Entity(repositoryClass="AppBundle\Repository\InvoiceNumeratorRepository")
*/
class InvoiceNumerator
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="translatedFormat", type="string", length=64)
*/
private $translatedFormat;
/**
* @var int
*
* @ORM\Column(name="currentValue", type="integer", options={"default": 0})
*/
private $currentValue = 0;
/**
* @var string
*
* @ORM\Column(name="current_number", type="string", length=64)
*/
private $currentNumber = '';
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set translatedFormat
*
* @param string $translatedFormat
*
* @return InvoiceNumerator
*/
public function setTranslatedFormat($translatedFormat)
{
$this->translatedFormat = $translatedFormat;
return $this;
}
/**
* Get translatedFormat
*
* @return string
*/
public function getTranslatedFormat()
{
return $this->translatedFormat;
}
/**
* Set currentValue
*
* @param integer $currentValue
*
* @return InvoiceNumerator
*/
public function setCurrentValue($currentValue)
{
$this->currentValue = $currentValue;
return $this;
}
/**
* Get currentValue
*
* @return int
*/
public function getCurrentValue()
{
return $this->currentValue;
}
/**
* @return string
*/
public function getCurrentNumber(): string
{
return $this->currentNumber;
}
/**
* @param string $currentNumber
* @return InvoiceNumerator
*/
public function setCurrentNumber(string $currentNumber): InvoiceNumerator
{
$this->currentNumber = $currentNumber;
return $this;
}
}
但在这种情况下,我的安装人员无法正常工作。 我还可以在新的Entity对象上设置值:
public function getInvoiceNumerator()
{
$invoiceNumerator = $this->createMock(InvoiceNumerator::class);
$invoiceNumerator->method('getTranslatedFormat')
->willReturn('FS-CM/{n}/2018/01');
$invoiceNumerator->method('getCurrentValue')
->willReturn('1');
$invoiceNumerator->method('getCurrentNumber')
->willReturn('FS-CM/1/2018/01');
return $invoiceNumerator;
}
在这种情况下,我的二传手正常工作。
有没有更好的方法呢?什么是最佳做法?
答案 0 :(得分:1)
基本上,您可以将模拟设置为仅模拟特定方法:
$invoiceNumerator = $this->getMockBuilder(InvoiceNumerator::class)
->setMethods(["getTranslatedFormat","getCurrentValue", "getCurrentNumber"])
->getMock();
可以在Mock Builder对象上调用
setMethods(array $methods)
来指定要用可配置的测试double替换的方法。其他方法的行为不会改变。如果调用setMethods(null),则不会替换任何方法。
答案 1 :(得分:1)
你几乎在你的问题“Phpunit partial mock + proxy Entity”中得到答案:你可以使用createPartialMock()
方法:
$invoiceNumerator = $this-> createPartialMock(
InvoiceNumerator::class,
['nameOfMockedMethod1', 'nameOfMockedMethod2']
);
此方法已在PHPUnit 5.5及更高版本中提供。如果您使用的是旧版本,则可以使用setMethods()
,但必须根据getMockBuilder()
返回的结果调用它,而不是createMock()
返回的对象(这是从第一个答案尝试接近后得到的错误):
$subject = $this->getMockBuilder(MyClass::class)
->setMethods(['method1', 'method2'])
->getMock();
但是,请注意createPartialMock()
稍微多一些。例如,它会自动禁用原始构造函数 - 这几乎总是你在测试中想要的(以及使用setMethods()
时你必须做的事情)。有关确切信息,请参阅文档。