轻松清理sinon存根

时间:2012-07-19 02:10:38

标签: javascript testing mocha stubbing sinon

有没有办法轻松重置所有使用mocha的beforeEach块干净利落的sinon spys模拟和存根。

我看到沙盒是一个选项,但我不知道如何使用沙盒来实现这个

beforeEach ->
  sinon.stub some, 'method'
  sinon.stub some, 'mother'

afterEach ->
  # I want to avoid these lines
  some.method.restore()
  some.other.restore()

it 'should call a some method and not other', ->
  some.method()
  assert.called some.method

9 个答案:

答案 0 :(得分:279)

Sinon通过使用Sandboxes提供此功能,可以使用几种方式:

// manually create and restore the sandbox
var sandbox;
beforeEach(function () {
    sandbox = sinon.sandbox.create();
});

afterEach(function () {
    sandbox.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
}

// wrap your test function in sinon.test()
it("should automatically restore all mocks stubs and spies", sinon.test(function() {
    this.stub(some, 'method'); // note the use of "this"
}));

答案 1 :(得分:10)

您可以使用sinon库中的this博客文章(2010年5月)中所示的sinon.collection。

sinon.collection api已经改变,使用它的方法如下:

beforeEach(function () {
  fakes = sinon.collection;
});

afterEach(function () {
  fakes.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
  stub = fakes.stub(window, 'someFunction');
}

答案 2 :(得分:10)

@keithjgrant回复的更新。

从版本 v2.0.0 开始, sinon.test 方法已移至a separate sinon-test module。要使旧测试通过,您需要在每个测试中配置此额外依赖项:

var sinonTest = require('sinon-test');
sinon.test = sinonTest.configureTest(sinon);

或者,您没有使用sinon-test并使用sandboxes

var sandbox = sinon.sandbox.create();

afterEach(function () {
    sandbox.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
} 

答案 3 :(得分:5)

如果你想要一个具有sinon的设置总是为所有测试重置自己:

helper.js中的

import sinon from 'sinon'

var sandbox;

beforeEach(function() {
    this.sinon = sandbox = sinon.sandbox.create();
});

afterEach(function() {
    sandbox.restore();
});

然后,在您的测试中:

it("some test", function() {
    this.sinon.stub(obj, 'hi').returns(null)
})

答案 4 :(得分:3)

请注意,当使用qunit而不是mocha时,您需要将它们包装在一个模块中,例如

module("module name"
{
    //For QUnit2 use
    beforeEach: function() {
    //For QUnit1 use
    setup: function () {
      fakes = sinon.collection;
    },

    //For QUnit2 use
    afterEach: function() {
    //For QUnit1 use
    teardown: function () {
      fakes.restore();
    }
});

test("should restore all mocks stubs and spies between tests", function() {
      stub = fakes.stub(window, 'someFunction');
    }
);

答案 5 :(得分:3)

restore()只是恢复存根功能的行为,但它不会重置存根的状态。您必须使用sinon.test包装测试并使用this.stub或在存根上单独调用reset()

答案 6 :(得分:3)

先前的答案建议使用import java.util.Scanner; public class HelloWorld{ public static void main(String []args){ int row, col, i, j; int arr[][] = new int[10][10]; Scanner scan = new Scanner(System.in); // enter row and column for array. System.out.print("Enter row for the array (max 10) : "); row = scan.nextInt(); System.out.print("Enter column for the array (max 10) : "); col = scan.nextInt(); // enter array elements. System.out.println("Enter " +(row*col)+ " Array Elements : "); for(i=0; i<row; i++) { for(j=0; j<col; j++) { arr[i][j] = scan.nextInt(); } } // the 2D array is here. System.out.print("The Array is :\n"); for(i=0; i<row; i++) { for(j=0; j<col; j++) { System.out.print(arr[i][j]+ " "); } System.out.println(); } // This prints the mid row if((row%2)!=0 ){ int midNumber = (row-1)/2; System.out.println("Mid Row is"); for(j=0; j<col; j++) { System.out.print(arr[midNumber][j]+ " "); } } // This prints the mid column if((col%2)!=0){ int midNumber = (col-1)/2; System.out.println("Mid Column is"); for(j=0; j<row; j++) { System.out.print(arr[j][midNumber]+ " "); } } } 完成此操作,但根据the documentation

  

自sinon@5.0.0起,sinon对象是默认的沙箱。

这意味着清理存根/模拟/间谍现在很容易:

sandboxes

答案 7 :(得分:0)

创建一个沙箱,将其用作所有间谍,存根,模拟和假货的黑匣子容器。

您要做的就是在第一个describe块中创建一个沙箱,以便可以在所有测试用例中访问它。一旦完成所有测试用例,就应该释放原始方法,并在afterEach挂钩中使用方法sandbox.restore()清理存根,以便在运行时释放占用的资源afterEach测试用例是通过或失败。

这里是一个示例:

 describe('MyController', () => {
    //Creates a new sandbox object
    const sandbox = sinon.createSandbox();
    let myControllerInstance: MyController;

    let loginStub: sinon.SinonStub;
    beforeEach(async () => {
        let config = {key: 'value'};
        myControllerInstance = new MyController(config);
        loginStub = sandbox.stub(ThirdPartyModule, 'login').resolves({success: true});
    });
    describe('MyControllerMethod1', () => {
        it('should run successfully', async () => {
            loginStub.withArgs({username: 'Test', password: 'Test'}).resolves();
            let ret = await myControllerInstance.run();
            expect(ret.status).to.eq('200');
            expect(loginStub.called).to.be.true;
        });
    });
    afterEach(async () => {
        //clean and release the original methods afterEach test case at runtime
        sandbox.restore(); 
    });
});

答案 8 :(得分:0)

下面将重置所有存根和嵌套存根。

Option Explicit

Sub Go_to_Today_Button()

    Dim previousMonday As Date
    previousMonday = Date - Weekday(Date, vbMonday) + 1

    Dim ws As Worksheet, iLastRow As Long
    Dim rngSearch As Range, rngFound As Range
    
    Set ws = ActiveSheet
    iLastRow = ws.Cells(Rows.Count, "B").End(xlUp).Row
    Set rngSearch = ws.Range("B3:B" & iLastRow)
       
    Set rngFound = rngSearch.Find(What:=previousMonday, After:=Range("B3"), _
        LookIn:=xlFormulas, LookAt:=xlWhole, _
        SearchOrder:=xlByRows, SearchDirection:=xlNext)

    If Not rngFound Is Nothing Then
        Application.Goto Reference:=rngFound, Scroll:=True
    Else
        MsgBox "Could not find " & previousMonday
    End If
End Sub

或者你做 sinon.reset();

喜欢 NameOfFunctiontionYouWantToReset.resetHistory();