You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Then I wanted to clean up the database after each unit test. ChatGPT led me to the conclusion that I should use transactions. It suggested that I should use:
Then after some chatting with the chat, I came to the conclusion that I should use queryRunner.startTransaction() and queryRunner.rollbackTransaction(). But it still doesn't want to work for me.
Please help me fix the below code.
import{Test,TestingModule}from'@nestjs/testing';import{UsersService}from'./users.service';import{AppModule}from'../../app.module';import{DataSource,QueryRunner}from'typeorm';import{DATA_SOURCE}from'../database/database.providers';import{runSeeders}from'typeorm-extension';import{ConfigService}from'@nestjs/config';describe('UsersService',()=>{letservice: UsersService;letmodule: TestingModule;letdataSource: DataSource;letqueryRunner: QueryRunner;letconfig: ConfigService;letcreateQueryRunner;letrelease;beforeAll(async()=>{module=awaitTest.createTestingModule({imports: [AppModule],}).compile();config=module.get<ConfigService>(ConfigService);dataSource=module.get<DataSource>(DATA_SOURCE);if(config.get<string>('NODE_ENV')==='testing'){console.info('Running seeders for testing environment');awaitrunSeeders(dataSource);}service=module.get<UsersService>(UsersService);});beforeEach(async()=>{queryRunner=dataSource.createQueryRunner();awaitqueryRunner.startTransaction();});afterEach(async()=>{awaitqueryRunner.rollbackTransaction();awaitqueryRunner.release();});afterAll(async()=>{awaitmodule.close();});it('should be defined',async()=>{awaitservice.create({firstName: 'FN',lastName: 'LN',email: 'bogdan@desmart.com'});awaitservice.create({firstName: 'FN2',lastName: 'LN2',email: 'bogdan2@desmart.com'});expect(service).toBeDefined();});it('should return a user',async()=>{constuser=awaitservice.findOneByEmail('bogdan@desmart.com');expect(user).toBeDefined();});});
Actual Behavior
It doesn't work.
Steps to reproduce
Run the above code and see that it doesn't work.
My Environment
| Dependency | Version |
| Operating System | Alpine Linux v3.19.1 Docker container |
| Node.js version | 18.20.2 |
| Typescript version | 5.3.3 |
| TypeORM version | typeorm@npm:0.3.19 |
| nestjs/typeorm | @nestjs/typeorm@npm:10.0.1 |
Additional Context
Through some trial and error, I came to this solution. I used the <<== comments to highlight lines that were added to the previous example.
import{Test,TestingModule}from'@nestjs/testing';import{UsersService}from'./users.service';import{AppModule}from'../../app.module';import{DataSource,QueryRunner}from'typeorm';import{DATA_SOURCE}from'../database/database.providers';import{runSeeders}from'typeorm-extension';import{ConfigService}from'@nestjs/config';describe('UsersService',()=>{letservice: UsersService;letmodule: TestingModule;letdataSource: DataSource;letqueryRunner: QueryRunner;letconfig: ConfigService;letcreateQueryRunner;letrelease;beforeAll(async()=>{module=awaitTest.createTestingModule({imports: [AppModule],}).compile();config=module.get<ConfigService>(ConfigService);dataSource=module.get<DataSource>(DATA_SOURCE);if(config.get<string>('NODE_ENV')==='testing'){console.info('Running seeders for testing environment');awaitrunSeeders(dataSource);}service=module.get<UsersService>(UsersService);});beforeEach(async()=>{queryRunner=dataSource.createQueryRunner();awaitqueryRunner.startTransaction();createQueryRunner=dataSource.createQueryRunner;// <<==release=queryRunner.release;// <<==dataSource.createQueryRunner=()=>queryRunner;// <<==queryRunner.release=()=>Promise.resolve();// <<==});afterEach(async()=>{awaitqueryRunner.rollbackTransaction();dataSource.createQueryRunner=createQueryRunner;// <<==queryRunner.release=release;// <<==awaitqueryRunner.release();});afterAll(async()=>{awaitmodule.close();});it('should be defined',async()=>{awaitservice.create({firstName: 'FN',lastName: 'LN',email: 'bogdan@desmart.com'});awaitservice.create({firstName: 'FN2',lastName: 'LN2',email: 'bogdan2@desmart.com'});expect(service).toBeDefined();});it('should return a user',async()=>{constuser=awaitservice.findOneByEmail('bogdan@desmart.com');expect(user).toBeDefined();});});
Explanation:
I suppose that almost every time a query to the database is made we use dataSource.createQueryRunner().query(<SOME SQL QUERY>), which creates a new queryRunner. But for transactions to work for us in our tests file we must use the same queryRunner each time a query is made. Above is shown how I figured out how to enforce this behavior. If anyone has a better solution, please feel free to share it. I hope that this problem in TypeORM will be fixed sometime soon, or some better workaround will be introduced.
Relevant Database Driver(s)
aurora-mysql
aurora-postgres
better-sqlite3
cockroachdb
cordova
expo
mongodb
mysql
nativescript
oracle
postgres
react-native
sap
spanner
sqlite
sqlite-abstract
sqljs
sqlserver
Are you willing to resolve this issue by submitting a Pull Request?
No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
The text was updated successfully, but these errors were encountered:
Issue description
Transactions don't work in tests
Expected Behavior
I posted an issue on stackoverflow:
I want to write such a unit test file that each time I run it, I run an instance of the entire application. This is ensured by this part:
Then I wanted to clean up the database after each unit test. ChatGPT led me to the conclusion that I should use transactions. It suggested that I should use:
But it didn't want to work for me.
Then after some chatting with the chat, I came to the conclusion that I should use
queryRunner.startTransaction()
andqueryRunner.rollbackTransaction()
. But it still doesn't want to work for me.Please help me fix the below code.
Actual Behavior
It doesn't work.
Steps to reproduce
Run the above code and see that it doesn't work.
My Environment
| Dependency | Version |
| Operating System | Alpine Linux v3.19.1 Docker container |
| Node.js version | 18.20.2 |
| Typescript version | 5.3.3 |
| TypeORM version | typeorm@npm:0.3.19 |
| nestjs/typeorm | @nestjs/typeorm@npm:10.0.1 |
Additional Context
Through some trial and error, I came to this solution. I used the
<<==
comments to highlight lines that were added to the previous example.Explanation:
I suppose that almost every time a query to the database is made we use
dataSource.createQueryRunner().query(<SOME SQL QUERY>)
, which creates a new queryRunner. But for transactions to work for us in our tests file we must use the samequeryRunner
each time a query is made. Above is shown how I figured out how to enforce this behavior. If anyone has a better solution, please feel free to share it. I hope that this problem in TypeORM will be fixed sometime soon, or some better workaround will be introduced.Relevant Database Driver(s)
Are you willing to resolve this issue by submitting a Pull Request?
No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
The text was updated successfully, but these errors were encountered: