import MockMethodFactory from './jsmockMethodFactory'; import TestDouble from '../testDouble'; /** @class Mock */ class Mock extends TestDouble { /** * @access private **/ constructor(name, type = 'object') { super(name, type); this.type = 'Mock'; } /** * should_receive make method in mock. * @memberof Mock * @instance * @param {string} methodName - method name in mock. * @function should_receive * @returns {MockMethod} * @example mock("obj").should_receive("something"); // obj.something(); mock("Sample",mock.INSTANCE).should_receive("something"); // let sample = new Sample(); // sample.something(); // class Test // end // let test = new Test(); mock(test).should_receive("something"); // test.something(); mock(Test,mock.INSTANCE).should_receive("instance"); // let test = new Test(); // test.instance() **/ should_receive(methodName) { return MockMethodFactory.getMethod(this.getTestDouble(), methodName); } /** * Return specific information called method. * @memberof Mock * @instance * @function verify * @example mock("obj").should_receive("something"); obj.something(); mock("obj").verify("something"); // {"total" : 1, param : {}} **/ verify(methodName) { const methodInfo = MockMethodFactory.getData(this.getTestDouble()).get(methodName); if (methodInfo) { if (methodInfo.record.total === 0) { throw new Error(`${methodName} isn't called.`); } else { return methodInfo.record; } } else { throw new Error(`${methodName} isn't method.`); } } /** * Return all information called methods. * @memberof Mock * @instance * @function verify_all * @example mock("obj").should_receive("something"); mock("obj").should_receive("something2"); obj.something(); obj.something2(); mock("obj").verify_all(); //{ // "something": {total" : 1, param : {}} // "something2": {total" : 1, param : {}} //} **/ verify_all() { const obj = MockMethodFactory.getData(this.getTestDouble()); const returnValue = {}; obj.forEach((v, i) => { if (i !== 'current_obj') returnValue[i] = this.verify(i); }); return returnValue; } /** * Resets specific information called method. * @memberof Mock * @instance * @function reset * @example mock("obj").should_receive("something"); mock("obj").should_receive("something2"); obj.something(); obj.something2(); mock("obj").verify("something"); // {"total" : 1, param : {}} mock("obj").verify("something2"); // {"total" : 1, param : {}} mock("obj").reset("something"); mock("obj").verify("something"); // throw new Error(`something isn't called.`); mock("obj").verify("something2"); // {"total" : 1, param : {}} **/ reset(methodName) { const obj = MockMethodFactory.getData(this.getTestDouble()); obj.get(methodName).record = { total: 0, param: {} }; } /** * Resets all information called methods. * @memberof Mock * @instance * @function reset_all * @example mock("obj").should_receive("something"); mock("obj").should_receive("something2"); obj.something(); obj.something2(); mock("obj").verify("something"); // {"total" : 1, param : {}} mock("obj").verify("something2"); // {"total" : 1, param : {}} mock("obj").reset_all(); mock("obj").verify("something"); // throw new Error(`something isn't called.`); mock("obj").verify("something2"); // throw new Error(`something2 isn't called.`); **/ reset_all() { for (const [key, value] of MockMethodFactory.getData(this.getTestDouble())) { if (key !== 'current_obj') { value.record = { total: 0, param: {} }; } } } } /** * @desc create mock in global. * @param {string|object|function|class} name - Mock object of name, object, function or class. * @param {string} type - Mock object of type. - mock.INSTANCE, mock.OBJECT(defalut) * @function mock * @returns {Mock} * @example // If `name` is string and `global` not found `name` object that mock create object in global. mock("obj").should_receive("something"); mock("Sample",mock.INSTANCE).should_receive("something"); // If `name` is object that mock don`t create object. mock(obj).should_receive("something"); mock(zlass).should_receive("something"); **/ export default function mockWrap(name, type) { if (this instanceof Mock) { this.createTestDouble(name, type); } else { return new Mock(name, type); } } /** * object string * @name mock.OBJECT * @global * @example mock("obj", mock.OBJECT); **/ mockWrap.OBJECT = 'object'; /** * instance string * @name mock.INSTANCE * @global * @example mock("obj", mock.INSTANCE); **/ mockWrap.INSTANCE = 'instance'; /** * `anything` return special string. * If you use `anything` in `with_param` that * `should_receive` execute method regardless of parameter value. * @name mock.anything * @global * @function anything * @returns {String} - '_js_mock_anything_param' * @example mock("obj").should_receive("something").with_param(1,mock.anything()).and_return("1"); **/ mockWrap.anything = () => '_js_mock_anything_param';