Saya menggunakan pengirim Symfony dalam kelas tersuai dalam projek Symfony 6. Saya menggunakan pendawaian automatik melalui petunjuk jenis dalam pembina kelas seperti ini:
class MyClass { public function __construct(private readonly MailerInterface $mailer) {} public function sendEmail(): array { // Email is sent down here try { $this->mailer->send($email); return [ 'success' => true, 'message' => 'Email sent', ]; } catch (TransportExceptionInterface $e) { return [ 'success' => false, 'message' => 'Error sending email: ' . $e, ]; } } }
Panggil kaedah sendEmail()
dalam pengawal dan semuanya berfungsi dengan baik.
Sekarang saya mahu menguji TransportException
s 是否被正确处理。为此,我需要邮件程序在我的测试中抛出 TransportException
s. Walau bagaimanapun, ini tidak berjaya seperti yang saya harapkan.
NOTA : Saya tidak boleh membuang pengecualian dengan menghantar alamat e-mel yang tidak sah kerana kaedah sendMail
hanya membenarkan alamat e-mel yang sah.
Perkara yang saya pernah cuba:
1) Gunakan program e-mel simulasi
// boot kernel and get Class from container $container = self::getContainer(); $myClass = $container->get('AppModelMyClass'); // create mock mailer service $mailer = $this->createMock(Mailer::class); $mailer->method('send') ->willThrowException(new TransportException()); $container->set('SymfonyComponentMailerMailer', $mailer);
Ternyata saya tidak dapat mensimulasikan Mailer
类,因为它是 final
.
2) Gunakan olok-olok (atau rintisan) MailerInterface
// create mock mailer service $mailer = $this->createStub(MailerInterface::class); $mailer->method('send') ->willThrowException(new TransportException()); $container->set('SymfonyComponentMailerMailer', $mailer);
Tiada ralat, tetapi tiada pengecualian yang dilemparkan. Perkhidmatan mel nampaknya tidak diganti.
3) Gunakan kelas MailerExceptionTester tersuai
// MailerExceptionTester.php <?php namespace AppTests; use SymfonyComponentMailerEnvelope; use SymfonyComponentMailerExceptionTransportException; use SymfonyComponentMailerMailerInterface; use SymfonyComponentMimeRawMessage; /** * Always throws a TransportException */ final class MailerExceptionTester implements MailerInterface { public function send(RawMessage $message, Envelope $envelope = null): void { throw new TransportException(); } }
Dalam ujian:
// create mock mailer service $mailer = new MailerExceptionTester(); $container->set('SymfonyComponentMailerMailer', $mailer);
Hasil yang sama seperti dalam 2)
4) Cuba tukar perkhidmatan MailerInterface dan bukannya Mailer
// create mock mailer service $mailer = $this->createMock(MailerInterface::class); $mailer->method('send') ->willThrowException(new TransportException()); $container->set('SymfonyComponentMailerMailerInterface', $mailer);
Mesej ralat: SymfonyComponentDependencyInjectionExceptionInvalidArgumentException:“SymfonyComponentMailerMailerInterface”服务是私有的,您无法替换它。
5) Tetapkan Antaramuka Mailer kepada umum
// services.yaml services: SymfonyComponentMailerMailerInterface: public: true
错误:无法实例化接口 SymfonyComponentMailerMailerInterface
6) Tambahkan alias untuk MailerInterface
// services.yaml services: app.mailer: alias: SymfonyComponentMailerMailerInterface public: true
Mesej ralat: SymfonyComponentDependencyInjectionExceptionInvalidArgumentException:“SymfonyComponentMailerMailerInterface”服务是私有的,您无法替换它。
Bagaimana untuk menggantikan perkhidmatan MailerInterface
yang disambungkan secara automatik dalam ujian?
Tempahan hendaklah betul pada percubaan pertama anda.
Tidak diuji, tetapi anda mendapat kelas sebagai objek, jadi kebergantungan pada perkhidmatan sudah diselesaikan sebelum mengejek. Ini sepatutnya menggantikan perkhidmatan dalam bekas dahulu dan kemudian dapatkan
MyClass
dari bekas.Namun, anda juga boleh melangkau membina bekas sepenuhnya. Hanya gunakan PhpUnit.
Saya cuba melakukan ini dan saya percaya saya telah menemui penyelesaian berdasarkan perkara yang telah anda cuba.
Dalam perkhidmatan
services.yaml
中,我重新声明mailer.mailer
saya dan tetapkannya kepada umum dalam persekitaran ujian:Persediaan ini sepatutnya menjadikan perkhidmatan Symfony Mailer berkelakuan sama seperti dahulu, tetapi kerana ia kini terbuka, kami boleh mengatasi kelas yang digunakan dalam bekas jika diperlukan.
Saya menyalin kelas Mailer tersuai yang anda tulis...