{"id":7164,"date":"2015-09-28T16:15:37","date_gmt":"2015-09-28T13:15:37","guid":{"rendered":"http:\/\/www.webcodegeeks.com\/?p=7164"},"modified":"2015-09-19T15:37:18","modified_gmt":"2015-09-19T12:37:18","slug":"javascript-unit-test-trap","status":"publish","type":"post","link":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/","title":{"rendered":"A JavaScript Unit Test Trap"},"content":{"rendered":"<p>You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the server.<\/p>\n<p>You\u2019ll need to refactor a few pages, but that\u2019s not a big deal. Your team has been pushing good unit testing practices, and you\u2019ve got great coverage for the affected code. You make the changes, verify that the unit tests still pass, maybe do a little manual testing for good measure, and then get everything committed.<\/p>\n<p>A few days later, the bug reports start rolling in. This column no longer shows the right data. When I run Test Case 5 the Widget Editor doesn\u2019t render correctly. The sort order for data on the home page is wrong.<\/p>\n<p>They\u2019re all for pages you modified, and nobody else has worked on those pages. You know your refactoring is to blame; but the unit tests were still passing! What the heck happened\u2026?<\/p>\n<h2>Where Do Mock Objects Come From?<\/h2>\n<p>In a strongly-typed language like Java, you probably rely heavily on a mock object framework. Through the magic of gclib the framework dynamically creates subclasses of your various services, repositories, etc. and serves up instances of those subclasses to replace each dependency used by your subject code.<\/p>\n<p>In JavaScript you don\u2019t need all that. In fact, you can\u2019t have all that, because nowhere do you definitively describe a \u201cclass\u201d for your objects. So your unit testing tool may provide some mocking support (like the \u201cspy\u201d functionality in Jasmine), but in general your unit tests can just build objects with whatever members they expect the subject code to access.<\/p>\n<p>Do you see the trap yet?<\/p>\n<h2>An Example in Two Languages<\/h2>\n<p>Your app handles orders. An order has a list of line items (each with a part number, quantity, and unit cost), a shipping address, and a shipping fee. To simplify the example, all costs are in whole dollars.<\/p>\n<p>In Java you define the following classes:<\/p>\n<pre class=\"brush:java\">public class Order {\r\n\tprivate List&lt;LineItem&gt; lineItems;\r\n\tprivate Address shipTo;\r\n\tprivate int shippingFee;\r\n\r\n\t\/\/ getters and setters ...\r\n}\r\n\r\npublic class LineItem {\r\n\tprivate string partNumber;\r\n\tprivate int quantity;\r\n\tprivate int unitCost;\r\n\r\n\t\/\/ getters and setters ...\r\n}\r\n<\/pre>\n<p>You also have an OrderService with the following method:<\/p>\n<pre class=\"brush:java\">public int calculateTotalCost(Order order) {\r\n\tint result = order.getShippingFee();\r\n\tfor (LineItem lineItem : order.getLineItems()) {\r\n\t\tresult += lineItem.quantity * lineItem.unitCost;\r\n\t}\r\n\r\n\treturn result;\r\n}\r\n<\/pre>\n<p>To test the OrderService, you\u2019ll want to pass in Order instances with known cost values and check that the correct total is returned. A pure approach would use mock objects with scripted responses for the getters, but for simple data objects with \u201clogic-less\u201d getters and setters, you might elect to create real Order objects instead.<\/p>\n<p>(If the test needed to verify that specific Order methods were used along the way, we\u2019d have to use a mock regardless; but we just want to test for the correct result.)<\/p>\n<pre class=\"brush:java\">\r\nOrder order = new Order();\r\nList&lt;LineItem&gt; lineItems = new ArrayList&lt;LineItem&gt;();\r\nLineItem item1 = new LineItem();\r\n\r\nitem1.setQuantity(2);\r\nitem1.setUnitCost(42);\r\nlineItems.add(item1);\r\norder.setLineItems(lineItems);\r\norder.setShippingFee(37);\r\n\r\nint result = orderService.calculateTotalCost(order);\r\nassertEquals(121, result);\r\n<\/pre>\n<p>Meanwhile, another team is putting together a proof-of-concept for a more JavaScript-centric architecture. Your Order class gets JSON bindings; the above test Order, for example, would serialize as:<\/p>\n<pre class=\"brush:javascript\">\r\n{ \"lineItems\": [\r\n    \"partNumber\": \"XL123\"\r\n  , \"quantity\": 2\r\n  , \"unitCost\": 42\r\n  ]\r\n, \"shipTo\": { \/*...*\/ }\r\n, \"shippingFee\": 37\r\n}\r\n<\/pre>\n<p>They have an orderService.js containing a JavaScript version of calculateTotalCost():<\/p>\n<pre class=\"brush:javascript\">\r\nvar calculateTotalCost = function (order) {\r\n\tvar result = order.shippingFee;\r\n\tfor (var i = 0; i &lt; order.lineItems.length; i++) {\r\n\t\tvar lineItem = order.lineItems[i];\r\n\t\tresult += lineItem.quantity * lineItem.unitCost;\r\n\t}\r\n\r\n\treturn result;\r\n};\r\n<\/pre>\n<p>They unit test their JavaScript code with Jasmine. If they need to pass in a simple data object, they build it on the spot. (Alternately, they might include helper functions in their test scripts to build these sorts of object.)<\/p>\n<pre class=\"brush:javascript\">\r\ndescribe(\"calculateTotalCost()\", function () {\r\n\tit(\"gives the total cost including shipping\", function () { \r\n\t\tvar order = {\r\n\t\t\t  orderItems: [{\r\n\t\t\t\t  quantity: 2\r\n\t\t\t\t, unitCost: 42\r\n\t\t\t  }]\r\n\t\t\t, shippingFee: 37\r\n\t\t};\r\n\t\tvar result = calculateTotalCost(order);\r\n\t\texpect(result).toEqual(121);\r\n\t});\r\n});\r\n<\/pre>\n<p>Now while the proof-of-concept is being evaluated, this logic has to be maintained in two places; but both teams agree that the test coverage is good (meaning, presumably, that there are more tests than we\u2019ve shown here), so nobody\u2019s too worried.<\/p>\n<h2>The Trap Is Sprung<\/h2>\n<p>Mid-way through the proof of concept period, you get a new requirement: Shipping costs need to be attributed to specific line items. The JavaScript team is off site, but you figure they can catch up; worst case their unit tests will alert them that something\u2019s broken, right?<\/p>\n<p>The Java team agrees that to avoid potential inconsistency, the shippingFee property will be removed from Order. There was some talk about minimizing interface changes by keeping the Order.getShippingFee() method (rewriting it to sum up the line items\u2019 shipping fee values), but everyone agrees that the order-level shipping fee should be removed from the JSON bindings in any case.<\/p>\n<p>You update the Java classes. The unit tests don\u2019t build since they reference nonexistent methods, so you fix them. Then you notice something weird\u2026<\/p>\n<p>The unit tests are passing. All of them. Even the JavaScript ones.<\/p>\n<p>The problem is that the JavaScript unit tests are making the same wrong assumptions about the Order structure as the code they\u2019re meant to test. In this case, it would likely get caught through even moderately good team communication; but in a bigger system, it\u2019s possible some code would slip through the cracks.<\/p>\n<p>And anyway, isn\u2019t the point of unit tests to alert you to a defect<em> even if you somehow miss it<\/em>?<\/p>\n<h2>So Where Should Mock Objects Come From<\/h2>\n<p>There are two ways to improve on this situation. Ideally we\u2019d like to remove assumptions about object structure from the unit test code. If we can\u2019t do that, maybe we can figure out how to validate those assumptions.<\/p>\n<p>In Java, our unit tests validate their assumptions about the structure of an order by trying to compile (and\/or run) against the Order and LineItem classes. In JavaScript, though, an object doesn\u2019t have a class.<\/p>\n<p>I noted above that the unit test scripts could contain helper functions for building data objects. We could make it a rule that all data objects must be obtained from helpers, and that the helpers must all be in a central library shared by all test scripts. Then updating that central library should cause all affected tests to fail. This would tend to isolate the assumptions in the test code. It does have its limitations. Ultimately our test codebase still contains unverified assumptions about the object structure, and there\u2019s no guarantee that each assumption can be isolated to a single helper function.<\/p>\n<p>Another option is to create an Order constructor. Of course, when we receive a JSON representation of an Order, it won\u2019t have gone through that constructor; so to make this meaningful, we have to use the received JSON to construct a \u201creal\u201d Order object that our code will operate on, and then throw the JSON representation away.<\/p>\n<p>At a glance, this feels wasteful; but then at some point in history many of the conventions we use to promote testability and maintainability were received with the same criticism. As a side benefit, our constructed object could use closures to conceal the internal state and provide access through getters and setters, providing some of the encapsulation we had in the Java world.<\/p>\n<p>When we first got the new requirement that changed our definition of an Order, we\u2019d update the Order constructor unit tests accordingly, which would lead us to fix the Order constructor itself. Once the constructor is fixed, our unit tests would fail when trying to call setShippingFee() on the order, much like the Java case, and we\u2019d have test failures pointing to each bit of code we need to fix.<\/p>\n<h2>Final Thoughts<\/h2>\n<p>This is likely not the only solution, and it may not be the best one; let us know how you\u2019ve addressed this issue in the comments below.<\/p>\n<p>Regardless, this should serve as a reminder that languages like JavaScript give us more than enough rope to hang ourselves. As the scale of your JavaScript projects increases, it becomes more important to self-impose some of the discipline that isn\u2019t enforced by the language.<\/p>\n<div class=\"attribution\">\n<table>\n<tbody>\n<tr>\n<td><span class=\"reference\">Reference: <\/span><\/td>\n<td><a href=\"http:\/\/keyholesoftware.com\/2015\/09\/15\/a-javascript-unit-test-trap\/\">A JavaScript Unit Test Trap<\/a> from our <a href=\"http:\/\/www.webcodegeeks.com\/wcg\/\">WCG partner<\/a> Keyhole Software at the <a href=\"http:\/\/keyholesoftware.com\/\">Keyhole Software<\/a> blog.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the server. You\u2019ll need to refactor a few pages, but that\u2019s not a big deal. Your team has been pushing good unit testing practices, and you\u2019ve got great &hellip;<\/p>\n","protected":false},"author":22,"featured_media":920,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-7164","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>A JavaScript Unit Test Trap - Web Code Geeks - 2026<\/title>\n<meta name=\"description\" content=\"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A JavaScript Unit Test Trap - Web Code Geeks - 2026\" \/>\n<meta property=\"og:description\" content=\"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\" \/>\n<meta property=\"og:site_name\" content=\"Web Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/webcodegeeks\" \/>\n<meta property=\"article:author\" content=\"http:\/\/facebook.com\/keyholesoftware\" \/>\n<meta property=\"article:published_time\" content=\"2015-09-28T13:15:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Keyhole Software\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/keyholesoftware\" \/>\n<meta name=\"twitter:site\" content=\"@webcodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Keyhole Software\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\"},\"author\":{\"name\":\"Keyhole Software\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10701460d97ebefdaf658a4f4535fff2\"},\"headline\":\"A JavaScript Unit Test Trap\",\"datePublished\":\"2015-09-28T13:15:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\"},\"wordCount\":1257,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"articleSection\":[\"JavaScript\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\",\"name\":\"A JavaScript Unit Test Trap - Web Code Geeks - 2026\",\"isPartOf\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"datePublished\":\"2015-09-28T13:15:37+00:00\",\"description\":\"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the\",\"breadcrumb\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.webcodegeeks.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JavaScript\",\"item\":\"https:\/\/www.webcodegeeks.com\/category\/javascript\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"A JavaScript Unit Test Trap\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#website\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"name\":\"Web Code Geeks\",\"description\":\"Web Developers Resource Center\",\"publisher\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.webcodegeeks.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\/\/www.webcodegeeks.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"contentUrl\":\"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/webcodegeeks\",\"https:\/\/x.com\/webcodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10701460d97ebefdaf658a4f4535fff2\",\"name\":\"Keyhole Software\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g\",\"caption\":\"Keyhole Software\"},\"description\":\"Keyhole is a midwest-based consulting firm with a tight-knit technical team. We work primarily with Java, JavaScript and .NET technologies, specializing in application development. We love the challenge that comes in consulting and blog often regarding some of the technical situations and technologies we face.\",\"sameAs\":[\"http:\/\/keyholesoftware.com\/\",\"http:\/\/facebook.com\/keyholesoftware\",\"http:\/\/linkedin.com\/company\/keyhole-software\",\"https:\/\/x.com\/http:\/\/twitter.com\/keyholesoftware\"],\"url\":\"https:\/\/www.webcodegeeks.com\/author\/keyhole-software\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A JavaScript Unit Test Trap - Web Code Geeks - 2026","description":"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/","og_locale":"en_US","og_type":"article","og_title":"A JavaScript Unit Test Trap - Web Code Geeks - 2026","og_description":"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the","og_url":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/","og_site_name":"Web Code Geeks","article_publisher":"https:\/\/www.facebook.com\/webcodegeeks","article_author":"http:\/\/facebook.com\/keyholesoftware","article_published_time":"2015-09-28T13:15:37+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","type":"image\/jpeg"}],"author":"Keyhole Software","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/keyholesoftware","twitter_site":"@webcodegeeks","twitter_misc":{"Written by":"Keyhole Software","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#article","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/"},"author":{"name":"Keyhole Software","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10701460d97ebefdaf658a4f4535fff2"},"headline":"A JavaScript Unit Test Trap","datePublished":"2015-09-28T13:15:37+00:00","mainEntityOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/"},"wordCount":1257,"commentCount":0,"publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","articleSection":["JavaScript"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/","url":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/","name":"A JavaScript Unit Test Trap - Web Code Geeks - 2026","isPartOf":{"@id":"https:\/\/www.webcodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage"},"image":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage"},"thumbnailUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","datePublished":"2015-09-28T13:15:37+00:00","description":"You\u2019re a few months into writing a shiny new web app, and the team just settled on some new standards for data structures used for communication with the","breadcrumb":{"@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#primaryimage","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2014\/10\/js-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.webcodegeeks.com\/javascript\/javascript-unit-test-trap\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.webcodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JavaScript","item":"https:\/\/www.webcodegeeks.com\/category\/javascript\/"},{"@type":"ListItem","position":3,"name":"A JavaScript Unit Test Trap"}]},{"@type":"WebSite","@id":"https:\/\/www.webcodegeeks.com\/#website","url":"https:\/\/www.webcodegeeks.com\/","name":"Web Code Geeks","description":"Web Developers Resource Center","publisher":{"@id":"https:\/\/www.webcodegeeks.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.webcodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.webcodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.webcodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.webcodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/webcodegeeks","https:\/\/x.com\/webcodegeeks"]},{"@type":"Person","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/10701460d97ebefdaf658a4f4535fff2","name":"Keyhole Software","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.webcodegeeks.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/68be341bef51b95ced09befd6a7e0ca930461d95f3a64285e03e7925b8f5de47?s=96&d=mm&r=g","caption":"Keyhole Software"},"description":"Keyhole is a midwest-based consulting firm with a tight-knit technical team. We work primarily with Java, JavaScript and .NET technologies, specializing in application development. We love the challenge that comes in consulting and blog often regarding some of the technical situations and technologies we face.","sameAs":["http:\/\/keyholesoftware.com\/","http:\/\/facebook.com\/keyholesoftware","http:\/\/linkedin.com\/company\/keyhole-software","https:\/\/x.com\/http:\/\/twitter.com\/keyholesoftware"],"url":"https:\/\/www.webcodegeeks.com\/author\/keyhole-software\/"}]}},"_links":{"self":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/7164","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/comments?post=7164"}],"version-history":[{"count":0,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/posts\/7164\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media\/920"}],"wp:attachment":[{"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/media?parent=7164"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/categories?post=7164"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.webcodegeeks.com\/wp-json\/wp\/v2\/tags?post=7164"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}