Giter VIP home page Giter VIP logo

Comments (1)

1111mp avatar 1111mp commented on July 22, 2024

Is this solution correct?
I don't think I'm writing code for automated testing, just trying to piece together code that doesn't report errors. : (

users.service.ts:

@Injectable()
export class UsersService {
  constructor(
    private readonly sequelize: Sequelize,
    @InjectModel(User)
    private readonly userModel: typeof User,
    @Inject(IORedisKey) private readonly redisClient: Redis,
  ) {}

  // ......

  async getUserModel(id: number): Promise<User> {
    return this.userModel.findOne({
      attributes: { exclude: ['pwd'] },
      where: { id },
    });
  }

  async findByAccount(account: string): Promise<User.UserInfo | null> {
    const trans = await this.sequelize.transaction();
    const user = await this.userModel.findOne({
      where: {
        account,
      },
      transaction: trans,
    });

    if (!user) return null;

    const role = await user.$get('role', { transaction: trans });
    const permissions = (
      await role.$get('permissions', { transaction: trans })
    ).map(({ id, name, desc }) => ({
      id,
      name,
      desc,
    }));

    await trans.commit();

    const { id: roleId, name: roleName, desc: roleDesc } = role;

    return {
      ...user.toJSON(),
      roleId,
      roleName,
      roleDesc,
      permissions,
    };
  }

 // ......
}

users.service.spec.ts:

import { Test, TestingModule } from '@nestjs/testing';
import { getModelToken } from '@nestjs/sequelize';
import { UsersService } from './users.service';
import { User as UserModel } from './models/user.model';
import { IORedisKey } from 'src/common/redis/redis.module';

import type { Redis } from 'ioredis';
import { Sequelize } from 'sequelize-typescript';

const testUser = {
  id: 10007,
  account: '176******',
  avatar: 'avatar.png',
  email: '[email protected]',
  regisTime: '2023-01-28 12:16:06',
  updateTime: '2023-01-29 14:01:35',
};

const testRole = {
  id: 5,
  name: 'admin',
  desc: '管理员',
};

const testPermissions = {
  id: 1,
  name: 'userDel',
  desc: 'Delete user',
};

describe('UsersService', () => {
  let service: UsersService,
    model: typeof UserModel,
    redisClient: Redis,
    sequelize: Sequelize;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UsersService,
        {
          provide: Sequelize,
          useValue: {
            transaction: jest.fn(),
          },
        },
        {
          provide: getModelToken(UserModel),
          useValue: {
            findOne: jest.fn(),
            create: jest.fn(() => testUser),
          },
        },
        { provide: IORedisKey, useValue: {} },
      ],
    }).compile();

    service = module.get<UsersService>(UsersService);
    model = module.get<typeof UserModel>(getModelToken(UserModel));
    redisClient = module.get<Redis>(IORedisKey);
    sequelize = module.get<Sequelize>(Sequelize);
  });

  afterEach(() => {
    jest.restoreAllMocks();
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  it('should get a single user by the method named getUserModel', () => {
    const findSpy = jest.spyOn(model, 'findOne');

    expect(service.getUserModel(10007));
    expect(findSpy).toBeCalledWith({
      attributes: { exclude: ['pwd'] },
      where: { id: 10007 },
    });
  });

  test('the method named findByAccount', async () => {
    // mock transaction
    const commit = jest.fn();
    const transaction = jest.fn(async () => ({ commit }) as any);
    const transSpy = jest
      .spyOn(sequelize, 'transaction')
      .mockImplementation(transaction);

    const permissionsStub = jest.fn(() => ({
        map: jest.fn(() => [testPermissions]),
      })),
      roleStub = jest.fn((key: string) => ({
        ...testRole,
        $get: permissionsStub,
      }));
    const findSpy = jest.spyOn(model, 'findOne').mockReturnValue({
      $get: roleStub,
      toJSON: jest.fn(() => testUser),
    } as any);

    const retVal = await service.findByAccount('176********');

    expect(transSpy).toBeCalledTimes(1);
    expect(findSpy).toBeCalledWith({
      where: { account: '176********' },
      transaction: await transaction(),
    });
    expect(commit).toBeCalledTimes(1);

    const { id: roleId, name: roleName, desc: roleDesc } = testRole;

    expect(retVal).toEqual({
      ...testUser,
      roleId,
      roleName,
      roleDesc,
      permissions: [testPermissions],
    });
  });
});
image

These codes look kind of stupid ...... Can anyone suggest the correct solution (or any idea).

from testing-nestjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.