{"id":13512479,"url":"https://github.com/NagRock/ts-mockito","last_synced_at":"2025-03-30T22:32:50.128Z","repository":{"id":41413310,"uuid":"67070528","full_name":"NagRock/ts-mockito","owner":"NagRock","description":"Mocking library for TypeScript","archived":false,"fork":false,"pushed_at":"2023-02-12T15:46:06.000Z","size":293,"stargazers_count":987,"open_issues_count":91,"forks_count":93,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-21T23:36:29.553Z","etag":null,"topics":["mock-library","mocking","mockito","stub","testing","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/NagRock.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-08-31T20:17:51.000Z","updated_at":"2025-02-23T07:12:53.000Z","dependencies_parsed_at":"2022-07-17T05:46:03.072Z","dependency_job_id":"78010bb7-e610-4c1c-becb-34c1b44728e4","html_url":"https://github.com/NagRock/ts-mockito","commit_stats":{"total_commits":243,"total_committers":28,"mean_commits":8.678571428571429,"dds":0.4979423868312757,"last_synced_commit":"89ce91b45b9ebb01a694049e7f74912266514de7"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NagRock%2Fts-mockito","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NagRock%2Fts-mockito/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NagRock%2Fts-mockito/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/NagRock%2Fts-mockito/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/NagRock","download_url":"https://codeload.github.com/NagRock/ts-mockito/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246296620,"owners_count":20754634,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mock-library","mocking","mockito","stub","testing","typescript"],"created_at":"2024-08-01T03:01:54.466Z","updated_at":"2025-03-30T22:32:50.089Z","avatar_url":"https://github.com/NagRock.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Testing Tools"],"sub_categories":[],"readme":"# ts-mockito [![build badge](https://travis-ci.org/NagRock/ts-mockito.svg?branch=master)](https://travis-ci.org/NagRock/ts-mockito) [![codecov](https://codecov.io/gh/NagRock/ts-mockito/branch/master/graph/badge.svg)](https://codecov.io/gh/NagRock/ts-mockito)\n\nMocking library for TypeScript inspired by http://mockito.org/\n\n## 1.x to 2.x migration guide\n[1.x to 2.x migration guide](https://github.com/NagRock/ts-mockito/wiki/ts-mockito-1.x-to-2.x-migration-guide)\n\n## Main features\n\n\n* Strongly typed\n* IDE autocomplete\n* Mock creation (`mock`) (also abstract classes) [#example](#basics)\n* Spying on real objects (`spy`) [#example](#spying-on-real-objects)\n* Changing mock behavior (`when`) via:\n\t* `thenReturn` - return value [#example](#stubbing-method-calls)\n\t* `thenThrow` - throw an error [#example](#throwing-errors)\n\t* `thenCall` - call custom method [#example](#custom-function)\n\t* `thenResolve` - resolve promise [#example](#resolving--rejecting-promises)\n\t* `thenReject` - rejects promise [#example](#resolving--rejecting-promises)\n* Checking if methods were called with given arguments (`verify`)\n\t* `anything`, `notNull`, `anyString`, `anyOfClass` etc. - for more flexible comparision\n\t* `once`, `twice`, `times`, `atLeast` etc. - allows call count verification [#example](#call-count-verification)\n\t* `calledBefore`, `calledAfter` - allows call order verification [#example](#call-order-verification)\n* Resetting mock (`reset`, `resetCalls`) [#example](#resetting-mock-calls), [#example](#resetting-mock)\n* Capturing arguments passed to method (`capture`) [#example](#capturing-method-arguments)\n* Recording multiple behaviors [#example](#recording-multiple-behaviors)\n* Readable error messages (ex. `'Expected \"convertNumberToString(strictEqual(3))\" to be called 2 time(s). But has been called 1 time(s).'`)\n\n## Installation\n\n`npm install ts-mockito --save-dev`\n\n## Usage\n\n### Basics\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\n\n// Getting instance from mock\nlet foo:Foo = instance(mockedFoo);\n\n// Using instance in source code\nfoo.getBar(3);\nfoo.getBar(5);\n\n// Explicit, readable verification\nverify(mockedFoo.getBar(3)).called();\nverify(mockedFoo.getBar(anything())).called();\n```\n\n### Stubbing method calls\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\n\n// stub method before execution\nwhen(mockedFoo.getBar(3)).thenReturn('three');\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\n\n// prints three\nconsole.log(foo.getBar(3));\n\n// prints null, because \"getBar(999)\" was not stubbed\nconsole.log(foo.getBar(999));\n```\n\n### Stubbing getter value\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\n\n// stub getter before execution\nwhen(mockedFoo.sampleGetter).thenReturn('three');\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\n\n// prints three\nconsole.log(foo.sampleGetter);\n```\n\n### Stubbing property values that have no getters\n\nSyntax is the same as with getter values.\n\nPlease note, that stubbing properties that don't have getters only works if [Proxy](http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-objects) object is available (ES6).\n\n### Call count verification\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\n\n// Some calls\nfoo.getBar(1);\nfoo.getBar(2);\nfoo.getBar(2);\nfoo.getBar(3);\n\n// Call count verification\nverify(mockedFoo.getBar(1)).once();               // was called with arg === 1 only once\nverify(mockedFoo.getBar(2)).twice();              // was called with arg === 2 exactly two times\nverify(mockedFoo.getBar(between(2, 3))).thrice(); // was called with arg between 2-3 exactly three times\nverify(mockedFoo.getBar(anyNumber()).times(4);    // was called with any number arg exactly four times\nverify(mockedFoo.getBar(2)).atLeast(2);           // was called with arg === 2 min two times\nverify(mockedFoo.getBar(anything())).atMost(4);   // was called with any argument max four times\nverify(mockedFoo.getBar(4)).never();              // was never called with arg === 4\n```\n\n### Call order verification\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\nlet mockedBar:Bar = mock(Bar);\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\nlet bar:Bar = instance(mockedBar);\n\n// Some calls\nfoo.getBar(1);\nbar.getFoo(2);\n\n// Call order verification\nverify(mockedFoo.getBar(1)).calledBefore(mockedBar.getFoo(2));    // foo.getBar(1) has been called before bar.getFoo(2)\nverify(mockedBar.getFoo(2)).calledAfter(mockedFoo.getBar(1));    // bar.getFoo(2) has been called before foo.getBar(1)\nverify(mockedFoo.getBar(1)).calledBefore(mockedBar.getFoo(999999));    // throws error (mockedBar.getFoo(999999) has never been called)\n```\n\n### Throwing errors\n\n``` typescript\nlet mockedFoo:Foo = mock(Foo);\n\nwhen(mockedFoo.getBar(10)).thenThrow(new Error('fatal error'));\n\nlet foo:Foo = instance(mockedFoo);\ntry {\n    foo.getBar(10);\n} catch (error:Error) {\n    console.log(error.message); // 'fatal error'\n}\n```\n\n### Custom function\n\nYou can also stub method with your own implementation\n\n``` typescript\nlet mockedFoo:Foo = mock(Foo);\nlet foo:Foo = instance(mockedFoo);\n\nwhen(mockedFoo.sumTwoNumbers(anyNumber(), anyNumber())).thenCall((arg1:number, arg2:number) =\u003e {\n    return arg1 * arg2; \n});\n\n// prints '50' because we've changed sum method implementation to multiply!\nconsole.log(foo.sumTwoNumbers(5, 10));\n```\n\n### Resolving / rejecting promises\n\nYou can also stub method to resolve / reject promise\n\n``` typescript\nlet mockedFoo:Foo = mock(Foo);\n\nwhen(mockedFoo.fetchData(\"a\")).thenResolve({id: \"a\", value: \"Hello world\"});\nwhen(mockedFoo.fetchData(\"b\")).thenReject(new Error(\"b does not exist\"));\n```\n\n### Resetting mock calls\n\nYou can reset just mock call counter\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\n\n// Some calls\nfoo.getBar(1);\nfoo.getBar(1);\nverify(mockedFoo.getBar(1)).twice();      // getBar with arg \"1\" has been called twice\n\n// Reset mock\nresetCalls(mockedFoo);\n\n// Call count verification\nverify(mockedFoo.getBar(1)).never();      // has never been called after reset\n```\n\nYou can also reset calls of multiple mocks at once `resetCalls(firstMock, secondMock, thirdMock)`\n\n### Resetting mock\n\nOr reset mock call counter with all stubs\n\n``` typescript\n// Creating mock\nlet mockedFoo:Foo = mock(Foo);\nwhen(mockedFoo.getBar(1)).thenReturn(\"one\").\n\n// Getting instance\nlet foo:Foo = instance(mockedFoo);\n\n// Some calls\nconsole.log(foo.getBar(1));               // \"one\" - as defined in stub\nconsole.log(foo.getBar(1));               // \"one\" - as defined in stub\nverify(mockedFoo.getBar(1)).twice();      // getBar with arg \"1\" has been called twice\n\n// Reset mock\nreset(mockedFoo);\n\n// Call count verification\nverify(mockedFoo.getBar(1)).never();      // has never been called after reset\nconsole.log(foo.getBar(1));               // null - previously added stub has been removed\n```\n\nYou can also reset multiple mocks at once `reset(firstMock, secondMock, thirdMock)`\n\n### Capturing method arguments\n\n``` typescript\nlet mockedFoo:Foo = mock(Foo);\nlet foo:Foo = instance(mockedFoo);\n\n// Call method\nfoo.sumTwoNumbers(1, 2);\n\n// Check first arg captor values\nconst [firstArg, secondArg] = capture(mockedFoo.sumTwoNumbers).last();\nconsole.log(firstArg);    // prints 1\nconsole.log(secondArg);    // prints 2\n```\n\nYou can also get other calls using `first()`, `second()`, `byCallIndex(3)` and more...\n\n### Recording multiple behaviors\n\nYou can set multiple returning values for same matching values\n\n``` typescript\nconst mockedFoo:Foo = mock(Foo);\n\nwhen(mockedFoo.getBar(anyNumber())).thenReturn('one').thenReturn('two').thenReturn('three');\n\nconst foo:Foo = instance(mockedFoo);\n\nconsole.log(foo.getBar(1));\t// one\nconsole.log(foo.getBar(1));\t// two\nconsole.log(foo.getBar(1));\t// three\nconsole.log(foo.getBar(1));\t// three - last defined behavior will be repeated infinitely\n```\n\nAnother example with specific values\n\n``` typescript\nlet mockedFoo:Foo = mock(Foo);\n\nwhen(mockedFoo.getBar(1)).thenReturn('one').thenReturn('another one');\nwhen(mockedFoo.getBar(2)).thenReturn('two');\n\nlet foo:Foo = instance(mockedFoo);\n\nconsole.log(foo.getBar(1));\t// one\nconsole.log(foo.getBar(2));\t// two\nconsole.log(foo.getBar(1));\t// another one\nconsole.log(foo.getBar(1));\t// another one - this is last defined behavior for arg '1' so it will be repeated\nconsole.log(foo.getBar(2));\t// two\nconsole.log(foo.getBar(2));\t// two - this is last defined behavior for arg '2' so it will be repeated\n```\n\nShort notation:\n\n``` typescript\nconst mockedFoo:Foo = mock(Foo);\n\n// You can specify return values as multiple thenReturn args\nwhen(mockedFoo.getBar(anyNumber())).thenReturn('one', 'two', 'three');\n\nconst foo:Foo = instance(mockedFoo);\n\nconsole.log(foo.getBar(1));\t// one\nconsole.log(foo.getBar(1));\t// two\nconsole.log(foo.getBar(1));\t// three\nconsole.log(foo.getBar(1));\t// three - last defined behavior will be repeated infinity\n```\n\nPossible errors:\n\n``` typescript\nconst mockedFoo:Foo = mock(Foo);\n\n// When multiple matchers, matches same result:\nwhen(mockedFoo.getBar(anyNumber())).thenReturn('one');\nwhen(mockedFoo.getBar(3)).thenReturn('one');\n\nconst foo:Foo = instance(mockedFoo);\nfoo.getBar(3); // MultipleMatchersMatchSameStubError will be thrown, two matchers match same method call\n\n```\n\n### Mocking interfaces\n\nYou can mock interfaces too, just instead of passing type to `mock` function, set `mock` function generic type\nMocking interfaces requires `Proxy` implementation\n\n``` typescript\nlet mockedFoo:Foo = mock\u003cFooInterface\u003e(); // instead of mock(FooInterface)\nconst foo: SampleGeneric\u003cFooInterface\u003e = instance(mockedFoo);\n```\n\n### Mocking types\n\nYou can mock abstract classes\n\n``` typescript\nconst mockedFoo: SampleAbstractClass = mock(SampleAbstractClass);\nconst foo: SampleAbstractClass = instance(mockedFoo);\n```\n\nYou can also mock generic classes, but note that generic type is just needed by mock type definition\n\n``` typescript\nconst mockedFoo: SampleGeneric\u003cSampleInterface\u003e = mock(SampleGeneric);\nconst foo: SampleGeneric\u003cSampleInterface\u003e = instance(mockedFoo);\n\n```\n\n### Spying on real objects\n\nYou can partially mock an existing instance:\n\n``` typescript\nconst foo: Foo = new Foo();\nconst spiedFoo = spy(foo);\n\nwhen(spiedFoo.getBar(3)).thenReturn('one');\n\nconsole.log(foo.getBar(3)); // 'one'\nconsole.log(foo.getBaz()); // call to a real method\n```\n\nYou can spy on plain objects too:\n\n``` typescript\nconst foo = { bar: () =\u003e 42 };\nconst spiedFoo = spy(foo);\n\nfoo.bar();\n\nconsole.log(capture(spiedFoo.bar).last()); // [42] \n```\n\n### Thanks\n\n* Szczepan Faber (https://www.linkedin.com/in/szczepiq) \n* Sebastian Konkol (https://www.linkedin.com/in/sebastiankonkol) \n* Clickmeeting (http://clickmeeting.com)\n* Michał Stocki (https://github.com/michalstocki)\n* Łukasz Bendykowski (https://github.com/viman)\n* Andrey Ermakov (https://github.com/dreef3)\n* Markus Ende (https://github.com/Markus-Ende)\n* Thomas Hilzendegen (https://github.com/thomashilzendegen)\n* Johan Blumenberg (https://github.com/johanblumenberg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNagRock%2Fts-mockito","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FNagRock%2Fts-mockito","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FNagRock%2Fts-mockito/lists"}