У меня есть определённая логика, которую необходимо покрыть тестами, а именно
public function handle(ConsumerMessage $message): bool
{
$action = $message->getAction();
$mpnIdBrandIdSkuMarketplaceIds = $this->converter->convert($message);
if (empty($mpnIdBrandIdSkuMarketplaceIds) === false) {
$mpnIds = ArrayHelper::arrayColumnUnique($mpnIdBrandIdSkuMarketplaceIds, self::MPN_ID_FIELD);
$this->eventManager->triggerEvent(new NewEventSystemMessageEvent($message, $mpnIds));
$allowedMpnIds = $this->allowedFcMpnIdsFilter->filter($mpnIds);
$allowedMpnIdsIndexedByMpnIds = array_combine($allowedMpnIds, $allowedMpnIds);
foreach ($mpnIdBrandIdSkuMarketplaceIds as $item) {
$mpnId = $item[self::MPN_ID_FIELD];
$marketplaceId = $item[self::MARKETPLACE_PRODUCT_ID_FIELD];
if (self::DELETE_ACTION === $action) {
if ($marketplaceId !== null) {
$this->identifiersBufferByAction[$action][$marketplaceId] = $marketplaceId;
$this->marketplaceProductIdToMpnId[$marketplaceId] = $mpnId;
}
} elseif (isset($allowedMpnIdsIndexedByMpnIds[$mpnId])) {
$this->identifiersBufferByAction[$action][$mpnId] = $mpnId;
}
}
}
foreach ($this->identifiersBufferByAction as $action => $identifiers) {
if ($this->maxBufferSize <= count($identifiers)) {
$this->innerFlush($action, $identifiers);
}
}
return true;
}
/**
* @throws InvalidArgumentException
* @throws Exception
*/
private function innerFlush(string $action, array $identifiers): void
{
$ids = array_keys($identifiers);
if (count($ids) > 0) {
$isDeleteAction = self::DELETE_ACTION === $action;
$trData = [];
if (!$isDeleteAction) {
foreach ($ids as $mpnProductId) {
$trData[] = [
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID => $mpnProductId,
ProductQueue::TABLE_COLUMN_OPERATION_TYPE => ProductQueue::ENUM_OPERATION_TYPE_UPDATE,
ProductQueue::TABLE_COLUMN_MARKETPLACE_PRODUCT_ID => null
];
}
$transaction = $this->insertOnDuplicateKeyUpdateTransactionFactory->factory(
ProductQueue::class,
$trData,
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID
]
);
} else {
foreach ($ids as $marketplaceProductId) {
$mpnProductId = $this->marketplaceProductIdToMpnId[$marketplaceProductId] ?? null;
if ($mpnProductId !== null) {
$trData[] = [
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID => $mpnProductId,
ProductQueue::TABLE_COLUMN_OPERATION_TYPE => ProductQueue::ENUM_OPERATION_TYPE_DELETE,
ProductQueue::TABLE_COLUMN_MARKETPLACE_PRODUCT_ID => $marketplaceProductId
];
}
}
$transaction = $this->insertOnDuplicateKeyUpdateTransactionFactory->factory(
ProductQueue::class,
$trData,
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID
]
);
$this->marketplaceProductIdToMpnId = [];
}
$this->tm->doTransaction($transaction);
}
$this->identifiersBufferByAction[$action] = [];
}
Можно заметить, что метод innerFlush вызывается в том случае, когда буфер полностью заполнен.
Я покрыла данную логику следующим, тестом, а именно для проверки update
/**
* @test
* @throws Exception
*/
public function updateHandleWithBufferOverflowTest(): void {
/** @var ConsumerMessage|MockInterface $message */
$message = Mockery::mock(ConsumerMessage::class);
$message->shouldReceive('getAction')->once()->with()->andReturn('update');
$converted = [
[
'mpn_id' => '11',
'carid_brand_id' => '111',
'sku' => 'sku1',
'marketplace_product_id' => '1',
],
[
'mpn_id' => '22',
'carid_brand_id' => '222',
'sku' => 'sku2',
'marketplace_product_id' => '2',
],
[
'mpn_id' => '33',
'carid_brand_id' => '333',
'sku' => 'sku3',
'marketplace_product_id' => '3',
],
[
'mpn_id' => '44',
'carid_brand_id' => '444',
'sku' => 'sku4',
'marketplace_product_id' => '4',
],
];
$this->converter->shouldReceive('convert')
->once()
->with($message)
->andReturn($converted);
$expectedEvent = new NewEventSystemMessageEvent($message);
$this->eventManager->shouldReceive('triggerEvent')
->once()
->with(
Mockery::on(
static function (NewEventSystemMessageEvent $actualEvent) use ($expectedEvent) {
return $expectedEvent->getMessage() === $actualEvent->getMessage();
}
)
);
$this->allowedFcMpnIdsFilter->shouldReceive('filter')
->once()
->with(['11', '22', '33', '44'])
->andReturn(['11', '22', '33', '44']);
$trData = [
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID => '11',
ProductQueue::TABLE_COLUMN_OPERATION_TYPE => ProductQueue::ENUM_OPERATION_TYPE_UPDATE,
ProductQueue::TABLE_COLUMN_MARKETPLACE_PRODUCT_ID => null,
],
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID => '22',
ProductQueue::TABLE_COLUMN_OPERATION_TYPE => ProductQueue::ENUM_OPERATION_TYPE_UPDATE,
ProductQueue::TABLE_COLUMN_MARKETPLACE_PRODUCT_ID => null,
],
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID => '33',
ProductQueue::TABLE_COLUMN_OPERATION_TYPE => ProductQueue::ENUM_OPERATION_TYPE_UPDATE,
ProductQueue::TABLE_COLUMN_MARKETPLACE_PRODUCT_ID => null,
],
];
$transaction = Mockery::mock(InsertOnDuplicateKeyUpdateTransaction::class);
$this->insertOnDuplicateKeyUpdateTransactionFactory->shouldReceive('factory')
->once()
->withArgs(
[
ProductQueue::class,
$trData,
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID
]
]
)
->andReturn($transaction);
$this->tm->shouldReceive('doTransaction')
->once()
->with($transaction);
$this->handler = new EventSystemHandler(
$this->converter,
$this->eventManager,
$this->tm,
$this->insertOnDuplicateKeyUpdateTransactionFactory,
$this->allowedFcMpnIdsFilter,
self::MAX_BUFFER_SIZE
);
$reflection = new ReflectionClass($this->handler);
$property = $reflection->getProperty('identifiersBufferByAction');
$property->setAccessible(true);
$bufferBefore = $property->getValue($this->handler);
self::assertEmpty($bufferBefore, 'Buffer must be empty before handle is called.');
$this->handler->handle($message);
$bufferAfterHandle = $property->getValue($this->handler);
var_dump('Buffer after handle:', $bufferAfterHandle);
$actualBuffer = $property->getValue($this->handler);
var_dump($actualBuffer);
$expectedBuffer = [
'update' => [
'44' => '44',
],
];
self::assertEquals(
$expectedBuffer,
$actualBuffer,
'The identifiersBufferByAction buffer must contain only identifiers that pass the filter'
);
$this->tm->shouldHaveReceived('doTransaction')->once();
}
Но я никак не могу выявить конкретно где ошибка и исправить её.
Текст ошибки: "Mockery\Exception\NoMatchingExpectationException : No matching handler found for Mockery_3_App_Transactions_Factories_InsertOnDuplicateKeyUpdateTransactionFactory::factory('Carid\Amazon\Model\Marketplace\Entities\ProductQueue', [0 => [...], 1 => [...], 2 => [...], 3 => [...]], [0 => 'mpn_product_id']). Either the method was unexpected or its arguments matched no expected argument list for this method"
Желтым подсвечивает следующая строка - $this->handler->handle($message);
Как мне это исправить? или же что добавить? Если убрать данную строку, то ожидаемый и актуальный буфер не являются равными.