{"id":559,"date":"2023-10-24T14:30:00","date_gmt":"2023-10-24T17:30:00","guid":{"rendered":"https:\/\/suspensao.blog.br\/descrenca\/?p=559"},"modified":"2023-10-29T19:15:35","modified_gmt":"2023-10-29T22:15:35","slug":"utilitarios-de-teste","status":"publish","type":"post","link":"https:\/\/suspensao.blog.br\/descrenca\/utilitarios-de-teste\/","title":{"rendered":"Substituindo m\u00e9todos de set-up por utilit\u00e1rios de teste"},"content":{"rendered":"\n<p><em>(Este \u00e9 um post que publiquei no <a href=\"https:\/\/web.archive.org\/web\/20100806130712\/http:\/\/blog.seatecnologia.com.br:80\/2010\/05\/20\/utilitirios-de-teste\">antigo blog da SEA Tecnologia<\/a>. Como ainda \u00e9 relevante, resolvi republic\u00e1-lo.)<\/em><\/p>\n\n\n\n<p>Uma das muitas aprendizagens que adquiri na antiga SEA Tecnologia \u00e9 a cria\u00e7\u00e3o de <em>utilit\u00e1rios de teste<\/em>.<\/p>\n\n\n\n<p>Utilit\u00e1rios de teste s\u00e3o uma maneira de reaproveitar c\u00f3digo em testes unit\u00e1rios. Usualmente, isso \u00e9 feito utilizando os m\u00e9todos <code>setUp<\/code> ou <code>@Before<\/code> dos casos de teste, mas isso tem algumas desvantagens. Por exemplo, em um caso de teste, podemos ter a seguinte inicializa\u00e7\u00e3o:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">private<\/span> Address address;\n<span class=\"hljs-keyword\">private<\/span> AddressDAO addressDAO;\n\n@Before\n<span class=\"hljs-keyword\">public<\/span> void setUp() {\n    address = <span class=\"hljs-keyword\">new<\/span> Address();\n    address.setStreet(<span class=\"hljs-string\">\"Rua fulano\"<\/span>);\n    address.setNumber(<span class=\"hljs-string\">\"123\/A\"<\/span>);\n    addressDAO = <span class=\"hljs-keyword\">new<\/span> AddressDAO();\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Essa inicializa\u00e7\u00e3o funciona bem no teste abaixo&#8230;<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Test\n<span class=\"hljs-keyword\">public<\/span> void testGetAllAddresses(){\n    addressDAO.addAddress(address);\n\n    <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses();\n\n    assertEquals(<span class=\"hljs-number\">1<\/span>, addresses.size());\n    assertEquals(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getStreet());\n    assertEquals(<span class=\"hljs-string\">\"123\/A\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getNumber());\n} <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Agora, se tivermos o teste a seguir, o objeto criado \u00e9 desperdi\u00e7ado:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Test\n<span class=\"hljs-keyword\">public<\/span> void testGetNoAddress() {\n    <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses();\n\n    assertEquals(<span class=\"hljs-number\">0<\/span>, addresses.size());\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Se o c\u00f3digo for como o seguinte, teremos redund\u00e2ncia de c\u00f3digo. tamb\u00e9m temos de decidir SE o outro objeto deve ser criado no <code>@Before<\/code> tamb\u00e9m ou no m\u00e9todo.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">@Test\n<span class=\"hljs-keyword\">public<\/span> void testGetAllAddressesMoreThanOne() {\n    addressDAO.addAddress(address);\n    Address address2 = <span class=\"hljs-keyword\">new<\/span> Address();\n    address2.setStreet(<span class=\"hljs-string\">\"Outra rua\"<\/span>);\n    address2.setNumber(<span class=\"hljs-string\">\"111\"<\/span>);\n    addressDAO.addAddress(address2);\n    <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses(); \n    assertEquals(<span class=\"hljs-number\">1<\/span>, addresses.size());\n    assertEquals(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getStreet());\n    assertEquals(<span class=\"hljs-string\">\"123\/A\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getNumber()); \n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Esses inconvenientes s\u00e3o menores quando comparados \u00e0 tarefa de criar uma rede de depend\u00eancias. Por exemplo, para testar uma classe <code>Person<\/code> que agrega um <code>Address<\/code> em um outro caso de teste, teremos de ter um <code>@Before<\/code> semelhante a esse:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">private<\/span> Person person;\n<span class=\"hljs-keyword\">private<\/span> Address address;\n<span class=\"hljs-keyword\">private<\/span> PersonDAO personDAO;\n\n@Before     \n<span class=\"hljs-keyword\">public<\/span> void setUp() {\n    address = <span class=\"hljs-keyword\">new<\/span> Address();\n    address.setStreet(<span class=\"hljs-string\">\"Rua fulano\"<\/span>);\n    address.setNumber(<span class=\"hljs-string\">\"123\/A\"<\/span>);\n    person = <span class=\"hljs-keyword\">new<\/span> Person();\n    person.setName(<span class=\"hljs-string\">\"Jo\u00e3o\"<\/span>);\n    person.setAddress(address);\n    personDAO = <span class=\"hljs-keyword\">new<\/span> PersonDAO();\n} <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>O c\u00f3digo para a cria\u00e7\u00e3o de endere\u00e7os foi duplicado, e \u00e9 dif\u00edcil criar as depend\u00eancias. Nesses exemplos, vemos casos simples, mas \u00e9 f\u00e1cil visualizar como a situa\u00e7\u00e3o ir\u00e1 se complicar.<\/p>\n\n\n\n<p>N\u00f3s solucionamos esse problema criando uma classe para criar esses objetos. Essa classe seria algo como isso:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">public <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestUtil<\/span> <\/span>{\n    public <span class=\"hljs-keyword\">static<\/span> Address utilCreateAddress(<span class=\"hljs-built_in\">String<\/span> street, <span class=\"hljs-built_in\">String<\/span> number) {\n        Address address = <span class=\"hljs-keyword\">new<\/span> Address();\n        address.setStreet(<span class=\"hljs-string\">\"Rua fulano\"<\/span>);\n        address.setNumber(<span class=\"hljs-string\">\"123\/A\"<\/span>);\n        <span class=\"hljs-keyword\">return<\/span> address;     \n    }\n\n    public <span class=\"hljs-keyword\">static<\/span> Person utilCreatePerson(<span class=\"hljs-built_in\">String<\/span> name, Address address) {\n        Person person = <span class=\"hljs-keyword\">new<\/span> Person();\n        person.setName(name);\n        person.setAddress(address);\n        <span class=\"hljs-keyword\">return<\/span> person;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Nossos casos de teste estendiam a <code>TestUtil<\/code>, facilitando a cria\u00e7\u00e3o de objetos:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">TestAddress2<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">TestUtil<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> AddressDAO addressDAO = <span class=\"hljs-keyword\">new<\/span> AddressDAO();\n\n    @Test\n    <span class=\"hljs-keyword\">public<\/span> void testGetAllAddresses() {\n        Address address = utilCreateAddress(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, <span class=\"hljs-string\">\"123\/A\"<\/span>);\n        addressDAO.addAddress(address);\n\n        <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses();\n\n        assertEquals(<span class=\"hljs-number\">1<\/span>, addresses.size());\n        assertEquals(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getStreet());\n        assertEquals(<span class=\"hljs-string\">\"123\/A\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getNumber());\n    }\n\n    @Test\n    <span class=\"hljs-keyword\">public<\/span> void testGetNoAddress() {\n        <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses();\n\n        assertEquals(<span class=\"hljs-number\">0<\/span>, addresses.size());\n    }\n\n    @Test\n    <span class=\"hljs-keyword\">public<\/span> void testGetAllAddressesMoreThanOne() {\n        Address address = utilCreateAddress(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, <span class=\"hljs-string\">\"123\/A\"<\/span>);\n        Address address2 = utilCreateAddress(<span class=\"hljs-string\">\"Outra rua\"<\/span>, <span class=\"hljs-string\">\"111\"<\/span>);\n        addressDAO.addAddress(address);\n        addressDAO.addAddress(address2);\n\n        <span class=\"hljs-keyword\">List<\/span>&lt;Address&gt; addresses = addressDAO.getAllAddresses();\n\n        assertEquals(<span class=\"hljs-number\">2<\/span>, addresses.size());\n        assertEquals(<span class=\"hljs-string\">\"Rua fulano\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getStreet());\n        assertEquals(<span class=\"hljs-string\">\"123\/A\"<\/span>, addresses.get(<span class=\"hljs-number\">0<\/span>).getNumber());\n    } \n} <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Como tamb\u00e9m precis\u00e1vamos frequentemente de um objeto qualquer, ou que apenas um ou outro par\u00e2metro fosse definido, cri\u00e1vamos variantes dos m\u00e9todos:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Address utilCreateAddress() {\n    <span class=\"hljs-keyword\">return<\/span> utilCreateAddress(<span class=\"hljs-string\">\"Qualquer\"<\/span>, <span class=\"hljs-string\">\"Qualquer\"<\/span>);\n}\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> Person utilCreatePerson() {\n    <span class=\"hljs-keyword\">return<\/span> utilCreatePerson(<span class=\"hljs-string\">\"Jos\u00e9\"<\/span>, utilCreateAddress());\n} <\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Aprendemos isto em um projeto um tanto complexo, com grandes redes de depend\u00eancias de objetos. O uso desses utilit\u00e1rios de teste viabilizou a pr\u00e1tica de <a href=\"https:\/\/web.archive.org\/web\/20100806130712\/http:\/\/pt.wikipedia.org\/wiki\/Test_Driven_Development\">TDD<\/a> no sistema. Era emocionante descobrir que, para criar aquele documento que dependia de sete outros documentos e uns cinco ou seis usu\u00e1rios, bastava chamar um m\u00e9todo.<\/p>\n\n\n\n<p>Naturalmente, h\u00e1 mais sobre nossos utilit\u00e1rios de teste do que foi escrito aqui, e pode haver mais ainda que sequer fizemos. (Por exemplo, pode ser interessante produzir utilit\u00e1rios de teste para classes espec\u00edficas, ao inv\u00e9s de um gigantesco utilit\u00e1rio) Entretanto, como a ideia \u00e9 bem simples, esperamos que esse pontap\u00e9 inicial lhe motive a pensar sobre o tema. At\u00e9 mais!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Este \u00e9 um post que publiquei no antigo blog da SEA Tecnologia. Como ainda \u00e9 relevante, resolvi republic\u00e1-lo.) Uma das muitas aprendizagens que adquiri na antiga SEA Tecnologia \u00e9 a cria\u00e7\u00e3o de utilit\u00e1rios de teste. Utilit\u00e1rios de teste s\u00e3o uma maneira de reaproveitar c\u00f3digo em testes unit\u00e1rios. Usualmente, isso \u00e9 feito utilizando os m\u00e9todos setUp [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[169,93],"tags":[77,139,59,98],"class_list":["post-559","post","type-post","status-publish","format-standard","hentry","category-java","category-testes-programacao","tag-desenvolvimento-orientado-a-testes","tag-java","tag-tdd","tag-testes-automatizados"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p23QLV-91","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/559","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/comments?post=559"}],"version-history":[{"count":12,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/559\/revisions"}],"predecessor-version":[{"id":581,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/posts\/559\/revisions\/581"}],"wp:attachment":[{"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/media?parent=559"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/categories?post=559"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/suspensao.blog.br\/descrenca\/wp-json\/wp\/v2\/tags?post=559"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}