为了账号安全,请及时绑定邮箱和手机立即绑定

如何对从包中导入的方法进行存根和间谍活动?

如何对从包中导入的方法进行存根和间谍活动?

Go
桃花长相依 2022-06-06 15:02:39
我是一名 JavaScript 和 Python 开发人员。这是一个使用jestjs测试框架的单元测试代码片段:index.ts:import dotenv from 'dotenv';export class OsEnvFetcher {  constructor() {    const output = dotenv.config();    if (output.error) {      console.log('Error loading .env file');      process.exit(1);    }  }}index.test.ts:import { OsEnvFetcher } from './';import dotenv from 'dotenv';describe('OsEnvFetcher', () => {  afterEach(() => {    jest.restoreAllMocks();  });  it('should pass', () => {    const mOutput = { error: new Error('parsed failure') };    jest.spyOn(dotenv, 'config').mockReturnValueOnce(mOutput);    const errorLogSpy = jest.spyOn(console, 'log');    const exitStub = jest.spyOn(process, 'exit').mockImplementation();    new OsEnvFetcher();    expect(dotenv.config).toBeCalledTimes(1);    expect(errorLogSpy).toBeCalledWith('Error loading .env file');    expect(exitStub).toBeCalledWith(1);  });});单元测试的结果: PASS  stackoverflow/todo/index.test.ts (11.08s)  OsEnvFetcher    ✓ should pass (32ms)  console.log    Error loading .env file      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)----------|---------|----------|---------|---------|-------------------File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|-------------------All files |     100 |       50 |     100 |     100 |                    index.ts |     100 |       50 |     100 |     100 | 6                 ----------|---------|----------|---------|---------|-------------------Test Suites: 1 passed, 1 totalTests:       1 passed, 1 totalSnapshots:   0 totalTime:        12.467s示例中的测试方法在使用Arrange、Act、Assert模式的 js 项目中非常常见。由于该dotenv.config()方法会做一些文件系统 I/O 操作,所以它有一个副作用。所以我们将为它制作一个存根或模拟。这样,我们的单元测试就没有副作用,并且在隔离的环境中进行测试。这同样适用于 python。我们可以使用unittest.mock模拟对象库来做同样的事情。我对这些单元测试方法非常满意。
查看完整描述

1 回答

?
三国纷争

TA贡献1804条经验 获得超7个赞

这是我基于此答案的解决方案:


osEnvFetcher.go:


package util


import (

    "log"

    "os"

    "github.com/joho/godotenv"

)


var godotenvLoad = godotenv.Load

var logFatal = log.Fatal


type EnvFetcher interface {

    Getenv(key string) string

}


type osEnvFetcher struct {}


func NewOsEnvFetcher() *osEnvFetcher {

    err := godotenvLoad()

    if err != nil {

        logFatal("Error loading .env file")

    }

    return &osEnvFetcher{}

}


func (f *osEnvFetcher) Getenv(key string) string {

    return os.Getenv(key)

}

osEnvFetcher_test.go:


package util


import (

    "testing"

    "errors"

)



func mockRestore(oGodotenvLoad func(...string) error, oLogFatal func(v ...interface{})) {

    godotenvLoad = oGodotenvLoad

    logFatal = oLogFatal

}


func TestOsEnvFetcher(t *testing.T) {

    // Arrange

    oGodotenvLoad := godotenvLoad

    oLogFatal := logFatal

    defer mockRestore(oGodotenvLoad, oLogFatal)

    var godotenvLoadCalled = false

    godotenvLoad = func(...string) error {

        godotenvLoadCalled = true

        return errors.New("parsed failure")

    }

    var logFatalCalled = false

    var logFatalCalledWith interface{}

    logFatal = func(v ...interface{}) {

        logFatalCalled = true

        logFatalCalledWith = v[0]

    }

    // Act

    NewOsEnvFetcher()

    // Assert

    if !godotenvLoadCalled {

        t.Errorf("godotenv.Load should be called")

    }

    if !logFatalCalled {

        t.Errorf("log.Fatal should be called")

    }

    if logFatalCalledWith != "Error loading .env file" {

        t.Errorf("log.Fatal should be called with: %s", logFatalCalledWith)

    }

}

覆盖测试的结果:


☁  util [master] ⚡  go test -v -coverprofile cover.out

=== RUN   TestOsEnvFetcher

--- PASS: TestOsEnvFetcher (0.00s)

PASS

coverage: 80.0% of statements

报道html记者:

//img1.sycdn.imooc.com//629da76b0001a2fc10200991.jpg



查看完整回答
反对 回复 2022-06-06
  • 1 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信