Yii2: Use custom Mailer class for running tests

Created on 24 Aug 2017  路  8Comments  路  Source: yiisoft/yii2

What steps will reproduce the problem?

I'm overriding Mailer class with my own and use it to create queue of emails.

When I run tests, it seems to be using another class (Codeception\Lib\Connector\Yii2\TestMailer).

What is the expected result?

Use custom Mailing class.

What do you get instead?

Exception with message for each test where mailing class with custom method myOwnMathod() is used:

[yii\base\UnknownMethodException] Calling unknown method: Codeception\Lib\Connector\Yii2\TestMailer::myOwnMathod()

Where myOwnMethod() is defined in my overriten mailer class, but as in tests it is using \yii\swiftmailer\Mailer, which certainly is missing that method.

Is there a way to set-up custom mailing class for tests?

| Q | A
| ---------------- | ---
| Yii version | 2.0.12
| PHP version | 5.5+
| Operating system | Ubuntu 14.04

Codeception

All 8 comments

I have the same problem https://github.com/Codeception/Codeception/issues/4011 when running the functional case, DavertMik mark it not a problem . so I temporary add the class in the $allowedOptions to use my own mailer class.
image

@bologer, you can use something like this Yii::$app->set('mailer', $mockMailer); in your test and Codeception hardcoded version will not be called.

@bologer you can try to redefine the malier's class before the test case start
maybe in the _before function of the cest file
public function _before(CpdfapiTester $I){
\Yii::$app->set('mailer', 'app\common\components\Mailer');
\Codeception\Lib\Connector\Yii2::$mailer= \Yii::$app->get('mailer');
}

or you can new a extention file to listen the case start . http://codeception.com/docs/08-Customization
then do the redefine class in the beforeTest
the Extension file
` use \Codeception\Events;

class MyExtension extends \Codeception\Extension
{
// list events to listen to
// Codeception\Events constants used to set the event

public static $events = array(
    Events::TEST_BEFORE => 'beforeTest',
);

public function beforeTest(\Codeception\Event\TestEvent $e) {
    \Yii::$app->set('mailer', 'app\common\components\Mailer');
    \Codeception\Lib\Connector\Yii2::$mailer= \Yii::$app->get('mailer');
}

}`

@JunelanMe this is nice, but it is kind of a work around.

@cebe , @samdark is there solutiuon Yii-like way to define custom mailing class for tests only?

@JunelanMe there is no need in both two lines in beforeTest method, each of the line gives the expected result but in a different way.
@bologer This is one of the way how you use DI containers, you're able to substitute implementations where you need it, in test environment, for example. So imho it will be preferable way.
Yii::$app->set('mailer', $mockMailer);

@StalkAlex, alright, when I try to make the following:

public function __before() {
    Yii::$app->set('mailer', 'common\models\mailer\Mailer');
}

I get the following error:

[ModuleException] Yii2: Mailer module is not mocked, can't test emails 

I get the same error message if I put this:

Yii::$app->set('mailer', 'common\models\mailer\Mailer');

Inside of the test methods that use mailing class.

I tried it like this:

Yii::$app->set('mailer', ['class' => 'common\models\mailer\Mailer'])

Still get the same error.

Any idea what is wrong with it?

@bologer just checked by myself, here's green test:

class TestTest extends Unit
{
    public function _before()
    {
        Yii::$app->set('mailer', ['class' => 'tests\codeception\_extensions\TestMailer']);
    }

    public function testIntanceIsValid()
    {
        $test = Yii::$app->get('mailer');
        expect_that($test instanceof TestMailer);
    }
}

Exception says that there is a problem with you configuration. In yii module there are different parts that can be included: init, orm, email and fixtures. Check those. Also I'm using last Codeception and Yii2 versions.

P.S. Are you using grabSentEmails method? Then here's problem in extra check.

@StalkAlex, thank you very much! It worked.

Was this page helpful?
0 / 5 - 0 ratings