Git Product home page Git Product logo

Comments (2)

realistschuckle avatar realistschuckle commented on June 28, 2024

@EugeneKochetov I'm not sure I understand your use case. Mocking a method means that we want to track its interaction with calling code. We write

testmock.mock('test').returns(100)

so that some code that invokes test mock.test() will get 100 as a result. When we call a method on a mock object that we have not declared, it will throw an exception. For example,

testmock.mock('test').returns(100);
testmock.unmockedMethod(); // this will throw an exception!

Because we had set no expectations for the method unmockedMethod in the previous example, it fails. This is sometimes called "strict mock" behavior. But, that can be a drag.

The following statement relieves us from the burden of encountering those exceptions thrown due to unmocked methods. It also frees us from testing arguments, returning return values, and the like. It just means, "make a method available on the mock object for my code under test to use."

testmock.ignore('test');
testmock.test(); // does NOT throw an exception

So, when you type

testmock.ignore('test');
testmock.mock('test');

you're declaring two different intents for the same method which should not work by design. If you don't care about tracking the method calls, just type

testmock.ignore('test');

If you do care about return values, arguments, or the number of times that a method gets called, then use something like

testmock.mock('test').takes(10).returns(30).times(5);

I hope that helps. Happy coding.

from nodemock.

EugeneKochetov avatar EugeneKochetov commented on June 28, 2024

Hi,

Thanks for reply.
I tried to add takes or returns after mock but it doesn't really change anything. testmock.mock('test') works in the same way as testmock.mock('test').takesAll(). I'm not sure if it is expected behaviour.
I'll try to explain my use case and why I need mock after ignore.
I'm testing a JS class that depends on other classes via require() function. I use mockery to substitute module with my own mock class. Class under test depends on many mocks but each test usually checks interaction with only one mock. To simplify my tests I create default mock objects (or rather stubs in this case) for every dependency before each test in beforeEach Mocha hook. In most cases these default mocks just ignore all methods of real dependency class.
Then in my test I want to replace ignored method with expectation relevant to test scenario but keep all irrelevant methods ignored.
Here is a simple example of my use case:

// dependency.js
module.exports = new function() {
    this.method1 = function() {
        console.log('method1');
    }

    this.method2 = function() {
        console.log('method2');
    }
}
// main.js
module.exports = function() {
    var dependency = require('dependency.js');

    this.open = function() {
        dependency.method1();
    }
    this.close = function() {
        dependency.method2();
    }
}
// mainclassTest.js
var nodemock = require('nodemock');
var mockery = require('mockery');

var dependencyMock = nodemock.mock('foo').fail();

function ResetDependencyMock(mocked) {
    mocked.reset();
    mocked.ignore('method1');
    mocked.ignore('method2');
}

mockery.registerMock('dependency.js', dependencyMock);
mockery.enable();

describe('MainClass', function() {

    var _mainObject = {};

    beforeEach('create test object and mocks', function(done) {
        ResetDependencyMock(dependencyMock);
        var MainClass = require('../main.js');
        _mainObject = new MainClass();
        done();
    });

    afterEach('destroy test object', function(done) {
        _mainObject = null;
        done();
    });

    describe('method open()', function() {
        it('should call dependency method1()', function() {
            dependencyMock.mock('method1').takesAll();          // exception here
            _mainObject.open();
            dependencyMock.assertThrows();
        });
    });

    describe('method close()', function() {
        it('should call dependency method1()', function() {
            dependencyMock.mock('method2').takesAll();          // exception here
            _mainObject.open();
            _mainObject.close();
            dependencyMock.assertThrows();
        });
    });
});

So, you can see that in the test for open method I assert only for method1. And in the test for close method I assert only for method1. This helps to keep tests small and simple.
Probably I misuse it and there is another way of simplifying things. If yes I'd appreciate your advice.

Regards,
Eugene.

from nodemock.

Related Issues (8)

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.