学说冲洗更新不同步到kerneltestcase中的工厂创建的对象
我有一个服务方法的测试新闻通讯:: Unsubscribe
。我正在尝试在testunsubscribesnewslettersubscriber()
中通过使用铸造工厂创建对象newslettersubscriber
,然后调用此nistubScribe
方法,然后正确更新了新闻通讯
。
正在测试的服务:
// NewsletterService.php
class NewsletterService
{
public function __construct(
private readonly EntityManagerInterface $doctrine,
private readonly LoggerInterface $logger,
private readonly MailerService $mailer,
private readonly NewsletterSubscriptionRepository $repo,
private readonly CustomerRepository $customerRepo
) { }
// ...
public function unsubscribe(string $email): void
{
$existing = $this->customerRepo->findOneNewsletterSubscriberByEmail($email);
if (!$existing) {
$this->logger->warning('Tried to unsubscribe non-existent subscriber', ['email' => $email]);
return;
}
if (!$existing->isSubscribedToNewsletter()) {
$this->logger->info('Tried to unsubscribe a non-subscriber', ['email' => $email]);
return;
}
$existing->getNewsletterSubscription()->setUnsubscribedAt(new DateTimeImmutable);
$this->doctrine->persist($existing);
$this->doctrine->flush();
}
}
测试:
// NewsletterServiceTest.php
class NewsletterServiceTest extends KernelTestCase
{
public function testUnsubscribesNewsletterSubscriber(): void
{
/** @var Proxy|NewsletterSubscriber $sub */
$sub = NewsletterSubscriberFixtures::new()->create(
[
'email' => '[email protected]',
'zipcode' => '12345',
'newsletterSubscription' => NewsletterSubscriptionFixtures::createOne([
'subscribedAt' => new DateTimeImmutable('-1 day'),
'unsubscribedAt' => null,
]),
]
);
$this->assertTrue($sub->isSubscribedToNewsletter());
/** @var NewsletterService $service */
$service = static::getContainer()->get(NewsletterService::class);
$service->unsubscribe('[email protected]');
// I have auto refresh on, but just to be clear:
$sub->refresh();
$this->assertNotTrue($sub->isSubscribedToNewsletter()); // fails
}
}
如您所见,unberscribe
方法从存储库中找到新闻通讯
。 (注意:它确实找到了,我进行了调试。)然后,它设置了Unsubscribedat
属性。 退缩
调用$ sub
仍然具有unsubScribedat = null
,情况并非如此,因为newsletsletterservice设置了这种情况,情况并非如此::取消订阅
,然后冲入数据库。
如果我写$ em = static :: getContainer() - > get(entityManagerInterface :: class)
,我可以在调试器中看到unsubSiverEdat
设置在中业务逻辑。
进一步挖掘:
如果我添加了设置
方法,则
protected function setUp(): void
{
\Zenstruck\Foundry\Test\TestState::bootFoundry((new Configuration())
->setManagerRegistry(
static::getContainer()->get(ManagerRegistry::class)
)
);
}
可以使用。这里的问题是,我在config/packages/test/zenstruck_foundry.yaml
中没有加载我的默认场所,我在工厂中需要。另外,上述设置
似乎不是做事的预期方法。
I have a test for a service method NewsletterService::unsubscribe
. I am trying to test it in testUnsubscribesNewsletterSubscriber()
by creating an object NewsletterSubscriber
with a Foundry Factory and then calling this unsubscribe
method, and then assert that the NewsletterSubscriber
was correctly updated.
Service that is being tested:
// NewsletterService.php
class NewsletterService
{
public function __construct(
private readonly EntityManagerInterface $doctrine,
private readonly LoggerInterface $logger,
private readonly MailerService $mailer,
private readonly NewsletterSubscriptionRepository $repo,
private readonly CustomerRepository $customerRepo
) { }
// ...
public function unsubscribe(string $email): void
{
$existing = $this->customerRepo->findOneNewsletterSubscriberByEmail($email);
if (!$existing) {
$this->logger->warning('Tried to unsubscribe non-existent subscriber', ['email' => $email]);
return;
}
if (!$existing->isSubscribedToNewsletter()) {
$this->logger->info('Tried to unsubscribe a non-subscriber', ['email' => $email]);
return;
}
$existing->getNewsletterSubscription()->setUnsubscribedAt(new DateTimeImmutable);
$this->doctrine->persist($existing);
$this->doctrine->flush();
}
}
Test:
// NewsletterServiceTest.php
class NewsletterServiceTest extends KernelTestCase
{
public function testUnsubscribesNewsletterSubscriber(): void
{
/** @var Proxy|NewsletterSubscriber $sub */
$sub = NewsletterSubscriberFixtures::new()->create(
[
'email' => '[email protected]',
'zipcode' => '12345',
'newsletterSubscription' => NewsletterSubscriptionFixtures::createOne([
'subscribedAt' => new DateTimeImmutable('-1 day'),
'unsubscribedAt' => null,
]),
]
);
$this->assertTrue($sub->isSubscribedToNewsletter());
/** @var NewsletterService $service */
$service = static::getContainer()->get(NewsletterService::class);
$service->unsubscribe('[email protected]');
// I have auto refresh on, but just to be clear:
$sub->refresh();
$this->assertNotTrue($sub->isSubscribedToNewsletter()); // fails
}
}
As you can see, the unsubscribe
method finds the NewsletterSubscriber
from the repository. (Note: it does find it, I debugged that.) It then sets the unsubscribedAt
property. After the unsubscribe
call the $sub
still has unsubscribedAt = null
, which shouldn't be the case as it was set by NewsletterService::unsubscribe
and flushed to database.
If I write $em = static::getContainer()->get(EntityManagerInterface::class)
, I can see in the debugger that unsubscribedAt
is set in $em->unitOfWork
, but not in $sub->object
. I think I can therefore say that this isn't a problem regarding the business logic.
Further digging:
If I add a setUp
method like below
protected function setUp(): void
{
\Zenstruck\Foundry\Test\TestState::bootFoundry((new Configuration())
->setManagerRegistry(
static::getContainer()->get(ManagerRegistry::class)
)
);
}
it works. The issue here is that my default locale in config/packages/test/zenstruck_foundry.yaml
isn't loaded, which I need in my factories. Also, the above setUp
doesn't seem to be the intended way of doing things.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我忘了添加
按 a>。该特征具有涉及内核的测试箱的
设置
功能(例如kerneltestcase
和webtestcase
)。I forgot to add
as per the documentation. This trait has a
setUp
function for test-cases involving the kernel (such asKernelTestCase
andWebTestCase
).