{"id":522,"date":"2016-03-27T12:24:03","date_gmt":"2016-03-27T10:24:03","guid":{"rendered":"http:\/\/joost.vunderink.net\/blog\/?p=522"},"modified":"2016-03-27T12:24:03","modified_gmt":"2016-03-27T10:24:03","slug":"sinon-vs-rewire-when-do-i-use-which","status":"publish","type":"post","link":"https:\/\/joost.vunderink.net\/blog\/2016\/03\/27\/sinon-vs-rewire-when-do-i-use-which\/","title":{"rendered":"sinon vs rewire: when do I use which?"},"content":{"rendered":"<p>In node.js testing, there are 2 helper modules that I use often: <a href=\"http:\/\/sinonjs.org\/\">sinon<\/a> and <a href=\"https:\/\/github.com\/jhnns\/rewire\">rewire<\/a>. Sinon allows you to monkey-patch functions, while rewire allows you to&#8230; monkey-patch functions. Both modules have other uses as well, but in this post I&#8217;m focusing on monkey-patching.<\/p>\n<p>So, in which situations should you use sinon and when should you use rewire for monkey-patching?<\/p>\n<p>In short: if you are testing module A, and inside module A there is a call to a function of module B, you should use sinon. If you want to monkey-patch a call to a function inside module A itself, you should use rewire (and optionally, sinon as well).<\/p>\n<p>Here is an example.<\/p>\n<pre class=\"lang:js decode:true\" title=\"a.js\">\/\/ a.js\r\n\r\nvar b = require('b');\r\n\r\nfunction testMe(num) {\r\n  return {\r\n    x: a1(num),\r\n    y: b.b1(num),\r\n  }\r\n}\r\n\r\nfunction a1(num) {\r\n  return 2 * num;\r\n}\r\n\r\nmodule.exports = {\r\n  test: test\r\n};\r\n<\/pre>\n<pre class=\"lang:js decode:true \" title=\"b.js\">\/\/ b.js\r\n\r\nfunction b1(num) {\r\n  return 5 * num;\r\n}\r\n\r\nmodule.exports = {\r\n  b1: b1\r\n};\r\n<\/pre>\n<p>In your test file, when you are testing <span class=\"lang:default decode:true  crayon-inline \">testMe<\/span>\u00a0, you can mock <span class=\"lang:default decode:true  crayon-inline \">b.b1<\/span>\u00a0 by doing this:<\/p>\n<pre class=\"lang:default decode:true \" title=\"Mocking b.b1\">var b = require('b');\r\nvar b1mock = sinon.mock(b, 'b1');\r\n<\/pre>\n<p>This works, because in node.js, each <span class=\"lang:default decode:true  crayon-inline \">require()<\/span>\u00a0&#8216;ed module is a singleton. So the <span class=\"lang:default decode:true  crayon-inline \">b<\/span>\u00a0 in your test file is the same as the <span class=\"lang:default decode:true  crayon-inline \">b<\/span>\u00a0 in <span class=\"lang:default decode:true  crayon-inline \">a.js<\/span>\u00a0. Therefore, sinon can overwrite the <span class=\"lang:default decode:true  crayon-inline \">b.b1<\/span>\u00a0 function in the test file, which results in the call to <span class=\"lang:default decode:true  crayon-inline \">b.b1<\/span>\u00a0 inside <span class=\"lang:default decode:true  crayon-inline \">testMe<\/span>\u00a0 ending up in sinon&#8217;s mock.<\/p>\n<p>Unfortunately, this doesn&#8217;t work for the <span class=\"lang:default decode:true  crayon-inline \">a1<\/span>\u00a0 call. This function is not exported by <span class=\"lang:default decode:true  crayon-inline \">a.js<\/span>\u00a0, and even if it was, overwriting it with sinon would not have any effect. The reason for this, is that a1 is called &#8220;directly&#8221; from testMe.<\/p>\n<p>One way to work around this, is to modify the source code in the following way.<\/p>\n<pre class=\"lang:js decode:true\" title=\"Modified a.js\">\/\/ a.js - modified (ugly! don't do this!)\r\n\r\nvar b = require('b');\r\n\r\nfunction test(num) {\r\n  return {\r\n    x: module.exports.a1(num),\r\n    y: b.b1(num),\r\n  }\r\n}\r\n\r\nfunction a1(num) {\r\n  return 2 * num;\r\n}\r\n\r\nmodule.exports = {\r\n  a1: a1,\r\n  test: test\r\n};\r\n<\/pre>\n<p>In your test file, you can now <span class=\"lang:default decode:true  crayon-inline \">require(&#8216;.\/a&#8217;)<\/span>\u00a0 and use sinon to mock <span class=\"lang:default decode:true  crayon-inline \">a.a1()<\/span>\u00a0. Ugh. This is not elegant at all.<\/p>\n<p>Fortunately, rewire allows us to overwrite even private functions. All you need to do in your test file is the following:<\/p>\n<pre class=\"lang:js decode:true\" title=\"Monkey-patching a.a1 using rewire and sinon\">var a = rewire('a');\r\nvar a1mock = sinon.mock();\r\n\r\n\/\/ Overwrite the private a1 function with the mock.\r\nvar restore = a.__set__('a1', a1mock);\r\n\r\n\/\/ Do your test.\r\n\r\n\/\/ Restore the original a1 function.\r\nrestore();\r\n<\/pre>\n<p>This is a bit more work, but at least you don&#8217;t need to change the source code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In node.js testing, there are 2 helper modules that I use often: sinon and rewire. Sinon allows you to monkey-patch functions, while rewire allows you to&#8230; monkey-patch functions. Both modules have other uses as well, but in this post I&#8217;m &hellip; <a href=\"https:\/\/joost.vunderink.net\/blog\/2016\/03\/27\/sinon-vs-rewire-when-do-i-use-which\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[176,177,10,272],"tags":[188,290,291,226,289,231,273,235],"class_list":["post-522","post","type-post","status-publish","format-standard","hentry","category-javascript","category-node-js","category-software-development","category-testing-software-development","tag-javascript-2","tag-monkey-patch","tag-monkey-patching","tag-node-js","tag-rewire","tag-sinon","tag-testing","tag-unit-test"],"_links":{"self":[{"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/posts\/522"}],"collection":[{"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/comments?post=522"}],"version-history":[{"count":1,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/posts\/522\/revisions"}],"predecessor-version":[{"id":523,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/posts\/522\/revisions\/523"}],"wp:attachment":[{"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/media?parent=522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/categories?post=522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/joost.vunderink.net\/blog\/wp-json\/wp\/v2\/tags?post=522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}