`
Код: Выделить всё
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 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] = [];
}
На основании этого я написал тест, который не проходит.
Код: Выделить всё
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']);
// Устанавливаем начальное состояние буфера с максимальным размером
$reflection = new ReflectionClass($this->handler);
$bufferProperty = $reflection->getProperty('identifiersBufferByAction');
$bufferProperty->setAccessible(true);
$bufferProperty->setValue($this->handler, [
'update' => [
'11' => '11', '22' => '22', '33' => '33',
],
]);
$expectedTransactionData = [
[
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,
$expectedTransactionData,
[
ProductQueue::TABLE_COLUMN_MPN_PRODUCT_ID
]
]
)
->andReturn($transaction);
$this->tm->shouldReceive('doTransaction')
->once()
->with($transaction);
$result = $this->handler->handle($message);
self::assertTrue($result, 'The method handle must return true on successful processing.');
$actualBuffer = $bufferProperty->getValue($this->handler);
$expectedBuffer = [
'update' => [
'44' => '44'
],
];
self::assertEquals(
$expectedBuffer,
$actualBuffer,
'The buffer should retain only the remaining identifiers after the transaction.'
);
$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 ` $result = $this->handler->handle($message);
все ломается и обрывается.
Подозреваю, что я неправильно написал логику транзакции и соответственно заполнения буфера. Помогите решить проблему
Я попробовал отладить код, и мне кажется, что основная проблема заключается в установке максимального размера буфера и размера транзакции. Максимальный размер буфера в моем тестовом файле равен трем и является константой. Итак, логично, что когда количество данных достигает трех и более, происходит транзакция и обновление. А остальные данные сохраняются в буфере.
очень нужна помощь
Подробнее здесь: https://stackoverflow.com/questions/793 ... on-phpunit
Мобильная версия