微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么在运行 API 测试时 Symfony DI 容器会增加服务的实例?

如何解决为什么在运行 API 测试时 Symfony DI 容器会增加服务的实例?

我有一个应该只有一个实例的服务,我确信 DI 容器会处理它。当我通过邮递员发送请求时,一切正常,容器总是返回相同的实例。我什至添加一个额外的字段,其中包含在对象创建过程中生成的用于调试的随机数。

class ReadModel
{
    private ?Database $database;

    // Temporary field for debugging purpose
    private int $tmp;

    public function __construct()
    {
        $this->database = null;

        $this->tmp = rand(1,1000);
    }

    public function setDatabase(Database $database): void
    {
        $this->database = $database;

        dump($this->tmp); // returns e.g. 836 when codeception test is run
    }

    public function getCollection(string $collectionName): Collection
    {
        dump($this->tmp); // returns e.g. 390 when codeception test is run

        return $this->database->selectCollection($collectionName);
    }
}

当 Postman(开发环境)发送请求时,dump() 函数返回的两个数字是相等的(同一个实例被注入到其他使用它的服务中)。但是当我运行 Codeception 测试时,此服务的行为有所不同。当我在一项服务中调用 setDatabase()ReadModel 方法并在另一项服务中调用 getCollection 方法时,我收到 $tmp 字段的两个不同值。这意味着 ReadModel 服务的两个不同实例已注入到我的服务中。在两种环境(开发和测试)中如何实现相同的行为?

ReadModel 服务是自动装配的,因此我不会粘贴 services.yaml 内容

我的技术栈:Symfony 5.1,Codeception 4.1

附注。通过 Codeception 测试,我指的是像这样的 end2end API 测试,而不是单元测试:

<?PHP

use Codeception\Util\HttpCode;

class CreateProductCest
{
    public function _before(ApiTester $I)
    {
        // Authentication stuff...
    }

    public function shouldCreateProductWithNoException(ApiTester $I)
    {
        $data = [
            'name' => 'test123',];

        $I->sendPost('/product/create',$data);

        $I->seeResponseIsJson();
        $I->seeResponseCodeIs(HttpCode::OK);
        $I->seeResponseContainsJson([]);
    }
}

ReadModel 对象的方法调用示例。大部分代码都被剪掉了,我只留下了相关部分的代码

class JwtDecodedListener
{
    private ReadModel $readModel;

    public function __construct(
        ReadModel $readModel
    ) {
        $this->readModel = $readModel;
    }

    public function onJWTDecoded(JWTDecodedEvent $event)
    {
        // some code
        $client = new Client("mongodb://{$mongoDbUser}:{$mongoDbPass}@{$this->mongoHost}/{$mongoDb}");
        $this->readModel->setDatabase($client->selectDatabase($mongoDbUser));
    }
}
class ProductProjection
{
    private ReadModel $readModel;

    public function __construct(
        ReadModel $readModel
    ) {
        $this->readModel = $readModel;
    }

    public function whenProductWasCreated(Product $product): void
    {
        // $collectionName is from a factory
        $collection = $this->readModel->getCollection($collectionName);
    }
}

编辑:正如评论中所建议的,我在 dump() 类的构造函数添加ReadModel 调用,我的结论是相同的。从邮递员执行的发布请求 - 一个构造函数校准。 Codeception 执行相同的请求 - 2 次构造函数调用。还是不知道是什么原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?