{"id":2774,"date":"2012-11-01T22:00:07","date_gmt":"2012-11-01T20:00:07","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=2774"},"modified":"2012-11-01T22:52:20","modified_gmt":"2012-11-01T20:52:20","slug":"testing-hadoop-programs-with-mrunit","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html","title":{"rendered":"Testing Hadoop Programs with MRUnit"},"content":{"rendered":"<div>\u00a0This post will take a slight detour from implementing the patterns found in <a href=\"http:\/\/www.amazon.com\/Data-Intensive-Processing-MapReduce-Synthesis-Technologies\/dp\/1608453421\" target=\"_blank\">Data-Intensive Processing with MapReduce<\/a> to discuss something equally important, testing. I was inspired in part from a presentation by <a href=\"http:\/\/www.tomwheeler.com\/\" target=\"_blank\">Tom Wheeler<\/a> that I attended while at the 2012 Strata\/Hadoop World conference in New York. When working with large data sets, unit testing might not be the first thing that comes to mind. However, when you consider the fact that no matter how large your cluster is, or how much data you have, the same code is pushed out to all nodes for running the MapReduce job, Hadoop mappers and reducers lend themselves very well to being unit tested. But what is not easy about unit testing Hadoop, is the framework itself. Luckily there is a library that makes testing Hadoop fairly easy \u2013 <a href=\"http:\/\/mrunit.apache.org\/\" target=\"_blank\">MRUnit<\/a>. MRUnit is based on JUnit and allows for the unit testing of mappers, reducers and some limited integration testing of the mapper \u2013 reducer interaction along with combiners, custom counters and partitioners. We are using the latest release of MRUnit as of this writing, 0.9.0. All of the code under test comes from the <a title=\"Working Through Data-Intensive Text Processing with MapReduce \u2013 Local Aggregation Part II\" href=\"http:\/\/codingjunkie.net\/text-processing-with-mapreduce-part-2\/\" target=\"_blank\">previous post<\/a> on computing averages using local aggregation.<\/div>\n<p><strong>Setup<\/strong><\/p>\n<p>To get started, download MRUnit from <a href=\"http:\/\/mrunit.apache.org\/general\/downloads.html\" target=\"_blank\">here<\/a>. After you have extracted the tar file, cd into the mrunit-0.9.0-incubating\/lib directory. In there you should see the following:<\/p>\n<ol>\n<li>mrunit-0.9.0-incubating-hadoop1.jar<\/li>\n<li>mrunit-0.9.0-incubating-hadoop2.jar<\/li>\n<\/ol>\n<p>As I\u2019m sure can guess, the mrunit-0.9.0-incubating-hadoop1.jar is for MapReduce version 1 of Hadoop and mrunit-0.9.0-incubating-hadoop2.jar is for working the new version of Hadoop\u2019s MapReduce. For this post, and all others going forward, we will be using hadoop-2.0 version from Cloudera\u2019s <a href=\"https:\/\/ccp.cloudera.com\/display\/SUPPORT\/CDH4+Downloadable+Tarballs\" target=\"_blank\">CDH4.1.1 release<\/a> so we will need the mrunit-0.9.0-incubating-hadoop2.jar file. I added MRUnit, JUnit and Mockito as libraries in Intellij (JUnit and Mockito are found in the same directory as the MRUnit jar files). Now that we have set up our dependencies, let\u2019s start testing.<\/p>\n<p><strong>Testing Mappers<\/strong><\/p>\n<p>Setting up to test a mapper is very straight forward and is best explained by looking at some code first. We will use the in-mapper combining example from the <a title=\"Working Through Data-Intensive Text Processing with MapReduce \u2013 Local Aggregation Part II\" href=\"http:\/\/codingjunkie.net\/text-processing-with-mapreduce-part-2\/\" target=\"_blank\">previous post<\/a>:<\/p>\n<pre class=\" brush:java\">@Test\r\npublic void testCombiningMapper() throws Exception {\r\n   new MapDriver&lt;LongWritable,Text,Text,TemperatureAveragingPair&gt;()\r\n           .withMapper(new AverageTemperatureCombiningMapper())\r\n           .withInput(new LongWritable(4),new Text(temps[3]))\r\n           .withOutput(new Text('190101'),new TemperatureAveragingPair(-61,1))\r\n           .runTest();\r\n }<\/pre>\n<p>Notice the fluent api style which adds the ease of creating the test. To write your test you would:<\/p>\n<ol>\n<li>Instantiate an instance of the MapDriver class parameterized exactly as the mapper under test.<\/li>\n<li>Add an instance of the Mapper you are testing in the withMapper call.<\/li>\n<li>In the withInput call pass in your key and input value, in this case a LongWritable with an arbitrary value and a Text object that contains a line from from the NCDC weather dataset contained in a String array called \u2018temps\u2019 that was set up earlier in the test (not displayed here as it would take away from the presentation).<\/li>\n<li>Specify the expected output in the withOutput call, here we are expecting a Text object with the value of \u201c190101\u2033 and a TemperatureAveragingPair object containing the values -61 (temperature) and a 1 (count).<\/li>\n<li>The last call runTest feeds the specified input values into the mapper and compares the actual output against the expected output set in the \u2018withOutput\u2019 method.<\/li>\n<\/ol>\n<p>One thing to note is the MapDriver only allows one input and output per test. You can call withInput and withOutput multiple times if you want, but the MapDriver will overwrite the existing values with the new ones, so you will only ever be testing with one input\/output at any time. To specify multiple inputs we would use the MapReduceDriver, covered a couple of sections later, but next up is testing the reducer.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><strong>Testing Reducers<\/strong><\/p>\n<p>Testing the reducer follows the same pattern as the mapper test. Again, let\u2019s start by looking at a code example:<\/p>\n<pre class=\" brush:java\">@Test\r\npublic void testReducerCold(){\r\n  List&lt;TemperatureAveragingPair&gt; pairList = new ArrayList&lt;TemperatureAveragingPair&gt;();\r\n      pairList.add(new TemperatureAveragingPair(-78,1));\r\n      pairList.add(new TemperatureAveragingPair(-84,1));\r\n      pairList.add(new TemperatureAveragingPair(-28,1));\r\n      pairList.add(new TemperatureAveragingPair(-56,1));\r\n\r\n      new ReduceDriver&lt;Text,TemperatureAveragingPair,Text,IntWritable&gt;()\r\n                .withReducer(new AverageTemperatureReducer())\r\n                .withInput(new Text('190101'), pairList)\r\n                .withOutput(new Text('190101'),new IntWritable(-61))\r\n                .runTest();\r\n    }<\/pre>\n<ol>\n<li>The test starts by creating a list of TemperatureAveragingPair objects to be used as the input to the reducer.<\/li>\n<li>A ReducerDriver is instantiated, and like the MapperDriver, is parameterized exactly as the reducer under test.<\/li>\n<li>Next we pass in an instance of the reducer we want to test in the withReducer call.<\/li>\n<li>In the withInput call we pass in the key of \u201c190101\u2033 and the pairList object created at the start of the test.<\/li>\n<li>Next we specify the output that we expect our reducer to emit, the same key of \u201c190101\u2033 and an IntWritable representing the average of the temperatures in the list.<\/li>\n<li>Finally runTest is called, which feeds our reducer the inputs specified and compares the output from the reducer against the expect output.<\/li>\n<\/ol>\n<p>The ReducerDriver has the same limitation as the MapperDriver of not accepting more than one input\/output pair. So far we have tested the Mapper and Reducer in isolation, but we would also like to test them together in an integration test. Integration testing can be accomplished by using the MapReduceDriver class. The MapReduceDriver is also the class to use for testing the use of combiners, custom counters or custom partitioners.<\/p>\n<p><strong>Integration Testing<\/strong><\/p>\n<p>To test your mapper and reducer working together, MRUnit provides the MapReduceDriver class. The MapReduceDriver class as you would expect by now, with 2 main differences. First, you parameterize the input and output types of the mapper and the input and output types of the reducer. Since the mapper output types need to match the reducer input types, you end up with 3 pairs of parameterized types. Secondly you can provide multiple inputs and specify multiple expected outputs. Here is our sample code:<\/p>\n<pre class=\" brush:java\">@Test\r\npublic void testMapReduce(){\r\n\r\nnew MapReduceDriver&lt;LongWritable,Text,\r\n                      Text,TemperatureAveragingPair,\r\n                      Text,IntWritable&gt;()\r\n                .withMapper(new AverageTemperatureMapper())\r\n                .withInput(new LongWritable(1),new Text(temps[0]))\r\n                .withInput(new LongWritable(2),new Text(temps[1]))\r\n                .withInput(new LongWritable(3),new Text(temps[2]))\r\n                .withInput(new LongWritable(4),new Text(temps[3]))\r\n                .withInput(new LongWritable(5),new Text(temps[6]))\r\n                .withInput(new LongWritable(6),new Text(temps[7]))\r\n                .withInput(new LongWritable(7),new Text(temps[8]))\r\n                .withInput(new LongWritable(8),new Text(temps[9]))\r\n                .withCombiner(new AverageTemperatureCombiner())\r\n                .withReducer(new AverageTemperatureReducer())\r\n                .withOutput(new Text('190101'),new IntWritable(-22))\r\n                .withOutput(new Text('190102'),new IntWritable(-40))\r\n                .runTest();\r\n    }<\/pre>\n<p>As you can see from the example above, the setup is the same as the MapDriver and the ReduceDriver classes. You pass in instances of the mapper, reducer and optionally a combiner to test. The MapReduceDriver allows us to pass in multiple inputs that have different keys. Here the \u2018temps\u2019 array is the same one referenced in the mapper sample and contains a few lines from the NCDC weather dataset and the keys in those sample lines are the months of January and February of the year 1901 represented as \u201c190101\u2033 and \u201c190102\u2033 respectively. This test is successful, so we gain a little more confidence around the correctness of our mapper and reducer working together.<\/p>\n<p><strong>Conclusion<\/strong><\/p>\n<p>Hopefully, we have made the case for how useful MRUnit can be for testing Hadoop programs. I\u2019d like to wrap this post up with some of my own observations. Although MRUnit makes unit testing easy for mapper and reducer code, the mapper and reducer examples presented here are fairly simple. If your map and\/or reduce code starts to become more complex, it\u2019s probably a better to decouple the code from the Hadoop framework and test the new classes on their own. Also, as useful as the MapReduceDriver class is for integration testing, it\u2019s very easy to get to a point where you are no longer testing your code, but the Hadoop framework itself, which has already been done. I\u2019ve come up with my own testing strategy that I intend to use going forward:<\/p>\n<ol>\n<li>Unit test the map\/reduce code.<\/li>\n<li>Possibly write one integration test with the MapReduceDriver class.<\/li>\n<li>As a sanity check, run a MapReduce job on a single node install (on my laptop) to ensure it runs on the Hadoop framework.<\/li>\n<li>Then run my code on a test cluster, on EC2 using Apache Whirr in my case.<\/li>\n<\/ol>\n<p>Covering how to set up a single node install on my laptop (OSX Lion) and standing up a cluster on EC2 using Whirr would make this post too long, so I\u2019ll cover those topics in the next one. Thanks for your time.<\/p>\n<p><strong>Resources<\/strong><\/p>\n<ul>\n<li><a title=\"Data-Intensive Text Processing with MapReduce\" href=\"http:\/\/www.amazon.com\/Data-Intensive-Processing-MapReduce-Synthesis-Technologies\/dp\/1608453421\" target=\"_blank\">Data-Intensive Processing with MapReduce<\/a> by Jimmy Lin and Chris Dyer<\/li>\n<li><a href=\"http:\/\/www.amazon.com\/Hadoop-Definitive-Guide-Tom-White\/dp\/1449311520\/ref=tmm_pap_title_0?ie=UTF8&amp;qid=1347589052&amp;sr=1-1\" target=\"_blank\">Hadoop: The Definitive Guide<\/a> by Tom White<\/li>\n<li><a title=\"Source Code\" href=\"https:\/\/github.com\/bbejeck\/hadoop-algorithms\" target=\"_blank\">Source Code<\/a> from blog<\/li>\n<li><a href=\"http:\/\/hadoop.apache.org\/docs\/r0.20.2\/api\/index.html\">Hadoop API<\/a><\/li>\n<li><a href=\"http:\/\/mrunit.apache.org\/\" target=\"_blank\">MRUnit<\/a> for unit testing Apache Hadoop map reduce jobs<\/li>\n<li><a title=\"Project Gutenberg\" href=\"http:\/\/www.gutenberg.org\/\" target=\"_blank\">Project Gutenberg<\/a> a great source of books in plain text format, great for testing Hadoop jobs locally.<\/li>\n<\/ul>\n<p>&nbsp;<br \/>\n<strong><em>Reference: <\/em><\/strong><a href=\"http:\/\/codingjunkie.net\/testing-hadoop-programs-with-mrunit\/\">Testing Hadoop Programs with MRUnit<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Bill Bejeck at the <a href=\"http:\/\/codingjunkie.net\/\">Random Thoughts On Coding<\/a> blog.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally important, testing. I was inspired in part from a presentation by Tom Wheeler that I attended while at the 2012 Strata\/Hadoop World conference in New York. When working with large data sets, unit testing &hellip;<\/p>\n","protected":false},"author":110,"featured_media":62,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[184,665],"class_list":["post-2774","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-apache-hadoop","tag-mrunit"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Testing Hadoop Programs with MRUnit<\/title>\n<meta name=\"description\" content=\"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally\" \/>\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.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Testing Hadoop Programs with MRUnit\" \/>\n<meta property=\"og:description\" content=\"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-11-01T20:00:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-11-01T20:52:20+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-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=\"Bill Bejeck\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bill Bejeck\" \/>\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.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html\"},\"author\":{\"name\":\"Bill Bejeck\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/69f9f11896bf9cfd7278b440efeda646\"},\"headline\":\"Testing Hadoop Programs with MRUnit\",\"datePublished\":\"2012-11-01T20:00:07+00:00\",\"dateModified\":\"2012-11-01T20:52:20+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html\"},\"wordCount\":1319,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"keywords\":[\"Apache Hadoop\",\"MRUnit\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html\",\"name\":\"Testing Hadoop Programs with MRUnit\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"datePublished\":\"2012-11-01T20:00:07+00:00\",\"dateModified\":\"2012-11-01T20:52:20+00:00\",\"description\":\"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/11\\\/testing-hadoop-programs-with-mrunit.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Testing Hadoop Programs with MRUnit\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/69f9f11896bf9cfd7278b440efeda646\",\"name\":\"Bill Bejeck\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"caption\":\"Bill Bejeck\"},\"description\":\"Husband, father of 3, passionate about software development.\",\"sameAs\":[\"http:\\\/\\\/codingjunkie.net\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Bill-Bejeck\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Testing Hadoop Programs with MRUnit","description":"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally","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.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html","og_locale":"en_US","og_type":"article","og_title":"Testing Hadoop Programs with MRUnit","og_description":"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally","og_url":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-11-01T20:00:07+00:00","article_modified_time":"2012-11-01T20:52:20+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","type":"image\/jpeg"}],"author":"Bill Bejeck","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bill Bejeck","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html"},"author":{"name":"Bill Bejeck","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/69f9f11896bf9cfd7278b440efeda646"},"headline":"Testing Hadoop Programs with MRUnit","datePublished":"2012-11-01T20:00:07+00:00","dateModified":"2012-11-01T20:52:20+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html"},"wordCount":1319,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","keywords":["Apache Hadoop","MRUnit"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html","url":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html","name":"Testing Hadoop Programs with MRUnit","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","datePublished":"2012-11-01T20:00:07+00:00","dateModified":"2012-11-01T20:52:20+00:00","description":"\u00a0This post will take a slight detour from implementing the patterns found in Data-Intensive Processing with MapReduce to discuss something equally","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/11\/testing-hadoop-programs-with-mrunit.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Testing Hadoop Programs with MRUnit"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/69f9f11896bf9cfd7278b440efeda646","name":"Bill Bejeck","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","caption":"Bill Bejeck"},"description":"Husband, father of 3, passionate about software development.","sameAs":["http:\/\/codingjunkie.net\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Bill-Bejeck"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/2774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/110"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=2774"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/2774\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/62"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=2774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=2774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=2774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}