服务中的模拟存储库,节点 TypeScript

Posted

技术标签:

【中文标题】服务中的模拟存储库,节点 TypeScript【英文标题】:Mock repository in a Service, node TypeScript 【发布时间】:2020-04-02 15:41:30 【问题描述】:

我正在尝试进行单元测试,为此我必须模拟this.orderRepository.findById (id); 方法,该方法接受存储库以通过其 ID 查找对象。返回值已经设置好了,但是我无法通过测试。我正在使用 jest 构建一个单一测试,这是我在 node 中使用 typescript 进行的第一次测试。

orderService.ts

import  OrderRepository  from '../repository/orderRepository';
import  Service, Inject,   from 'typedi';


@Service()
export default class OrderService 
 constructor(
  private orderRepository: OrderRepository,
  @Inject('logger') private logger
) 

public async FindById(id: string)
try
  const orderRecord = await this.orderRepository.findById(id);

  return orderRecord;
  catch (e) 
  this.logger.error(e);
  throw e;
 

orderRepository.ts

 import Inject from 'typedi';

 export class OrderRepository 
  constructor(
   @Inject('orderModel') private orderModel: 
   Models.OrderModel
  ) 

  public async findById(id: any) 
   return this.orderModel.findById(id);
  

userService.test.ts

import OrderService from '../src/services/order';
import  OrderRepository  from '../src/repository/orderRepository';
import Order from '../src/models/order';

const orderData = id_product: "564sd654asd5as64d", quantity: 3, 
orderStatus: "registeredOrder", deliveryDateResquested: "2019-12-25";
let orderModel = new Order(orderData);

describe('Order', () => 
  let instance: OrderService;
  instance = Container.get(OrderService);
var orderRepository: OrderRepository;
var logger;

test('FindById', async () => 
  var service = new OrderService(orderRepository, logger);
  const spy = OrderRepository.prototype.findById = jest.fn();
  spy.mockReturnValue(orderModel);
  const result = service.FindById("cenas");
  expect(result).toBe(orderModel);

  spy.mockRestore();
)

结果测试

  Order
✕ FindById (7ms)

● Order › FindById

expect(received).toBe(expected) // Object.is equality

Expected: "_id": "5def6ec34bf18833fa2afcb0", "id_product": 
"564sd654asd5as64d", "orderStatus": "registeredOrder", "quantity": 3, 
"requestDate": 2019-12-10T10:09:07.139Z
Received: 

Difference:

- Expected
+ Received

- Object 
-   "_id": "5def6ec34bf18833fa2afcb0",
-   "id_product": "564sd654asd5as64d",
-   "orderStatus": "registeredOrder",
-   "quantity": 3,
-   "requestDate": 2019-12-10T10:09:07.139Z,
- 
+ Promise 

  22 |     spy.mockReturnValue(orderModel);
  23 |     const result = myclass.FindById("cenas");
> 24 |     expect(result).toBe(orderModel);
     |                    ^
  25 | 
  26 |     spy.mockRestore();
  27 |   )

  at Object.<anonymous> (tests/userService.test.ts:24:20)

   Test Suites: 1 failed, 1 total
   Tests:       1 failed, 1 total
   Snapshots:   0 total
   Time:        2.718s
   Ran all test suites.
   npm ERR! Test failed.  See above for more details.

【问题讨论】:

【参考方案1】:

我建议你试试moq.ts 库。它使您能够模拟类方法的输入和输出。例如:

const orderRepositoryMock = new Mock<OrderRepository>()
    .setup(instance => instance.findById("someID")
    .returns(orderModel)
    .object()

var service = new OrderService(orderRepositoryMock, logger);
const result = service.FindById("someID");
expect(result).toBe(orderModel); // or assert specific properties

如果你使用mongoose,你可以试试mock-mongoose lib。当调用 mongoose.connect 时,Mockgoose 通过在背面启动 mongod 来提供测试数据库。默认情况下,它在没有持久性的内存存储中使用。

【讨论】:

此库不适用于异步。你知道起订量异步返回的好库吗?

以上是关于服务中的模拟存储库,节点 TypeScript的主要内容,如果未能解决你的问题,请参考以下文章

用于测试的 Symfony 模拟存储库

如何将 npmjs.com 存储库中的 React 相关节点包转换为 ES5?

没有存储库的建议数据访问模式

模拟函数没有被调用

java数据结构与算法:java代码模拟带头节点单向链表的业务

用于节点 JS 验收测试的开发 API