如何使用 ts-sinon 存根嵌套依赖项

How to stub nested dependecies with ts-sinon

我得到了一个简单的单元测试,代码如下:

my-pubsub.spec.ts

import * as tsSinon from 'ts-sinon';

import { myPubSubFunction } from './my-pubsub';
import * as sendEmail from './send-mail';


describe("Notifications PubSub tests", () => {

  it("Should trigger audit", (done) => {
    const today = new Date()
    const data = {
     ( my data )
    }

    const spy = tsSinon.default.spy(sendEmail, "sendNotificationMessage")

    const dataBuffer = Buffer.from(JSON.stringify(data))

    // Call tested function and verify its behavior
    myPubSubFunction(dataBuffer)

    setTimeout(() => {
      // check if spy was called
      tsSinon.default.assert.calledOnce(spy)
      done()
    }, 100)
  })
})

并且 my-pubsub.tssend-mail 调用了一个函数,其中包含一个函数来设置 Api 键

import * as sgMail from '@sendgrid/mail';

sgMail.setApiKey(
  "MyKey"
) // error in here

export function sendNotificationMessage(mailConfig: any) {
const defaultConfig = {
    from: {
      email: "noreply@mymail.com",
      name: "my name",
    },
    template_id: "my template",
  }

  const msg = { ...defaultConfig, ...mailConfig }

  return sgMail.send(msg)
}

但是当 运行 我的测试出现以下错误 TypeError: sgMail.setApiKey is not a function

编辑:向发送邮件代码添加了更多代码。 您可以在下面找到更多关于 my-pubsub.ts

的代码

my-pubsub.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';
import moment = require('moment');

import { IModel, ModelType } from '../models/model.model';
import { sendNotificationMessage } from '../shared/send-mail';

const { PubSub } = require("@google-cloud/pubsub")

try {
  admin.initializeApp()
} catch (e) {}
const db = admin.firestore()
const pubSubClient = new PubSub()

export const myPubSubTrigger = functions.pubsub
  .topic("on-trigger")
  .onPublish(async (message) => {
    console.log("version 1")

    const myMessage = Buffer.from(message.data, "base64").toString("utf-8")

    const data: IModel = JSON.parse(myMessage)

    ( logic to create my object )

    /**
     * Send email
     */
    const result: any = await sendNotificationMessage(myObject)

    /**
     * Check result
     */
    if (result[0].statusCode === 202) {
        await docRef.update({ emailSent: true })
    } 
   ( another publish to audit the action )
  })

问题不在于测试本身,而是 @sendgrid/mail:

的错误类型定义
// OK
import sgMail from "@sendgrid/mail";
import { default as sgMail2 } from "@sendgrid/mail";

console.log(sgMail === sgMail2);

sgMail.setApiKey("SG.key");
sgMail2.setApiKey("SG.key2");

// BROKEN
// type definition does not match runtime shape
import * as sgMailIncorrectlyTyped from "@sendgrid/mail";
console.log(sgMailIncorrectlyTyped, sgMailIncorrectlyTyped.setApiKey === undefined);

STACKBLITZ