Rafael Noronha

closing the gap between business and technology

Archive for February, 2009

Testando a engine de blog com BDD

without comments

Continuando o projeto de uma engine de Blog, resolvi dar início ao plano de testes unitários.
Optei por utilizar a abordagem Behavior Driven Development, o que alguns chamam de uma evolução do TDD.

O interessante desta abordagem é que o código da base de testes fica limpo, focado nas regras de negócio.
Quando algum teste falhar, dificilmente o programador perderá tempo entendendo porque o teste parou de funcionar e o quê precisa ser consertado.

Para ajudar a testar os objetos de maneira desacoplada, resolvi adotar o framework Rhino Mocks.
Para aplicar o BDD utilizei o NBehave, que neste caso está apoiado sobre o NUnit.

Ainda estou estudando como implentar mocks de maneira adequada e também amadurecendo a utilização das técnicas de BDD.
Mas gostei bastante do resultado.



using NBehave.Narrator.Framework;
using NBehave.Spec.NUnit;
using NUnit.Framework;
using Rhino.Mocks;
using Specification = NUnit.Framework.TestAttribute;

namespace MyCompany.Web.Blog.Tests
{
    [TestFixture]
    public class Author_publishing_entries : SpecBase
    {
        private IBlogContext context;
        private Entry entry;
        private Story story;
        private MockRepository mocks;

        [Story]
        public override void MainSetup()
        {
            base.MainSetup();
            PrepareContext();

            story = new Story("Publishing");

            story.AsA("blog author")
                .IWant("to be able to publish an entry")
                .SoThat("it can be shared with a reader");
        }

        private void PrepareContext()
        {
            entry = new Entry("someTitle", "someSlug", "someIntro",
                "someContent", null);

            mocks = new MockRepository();
            context = mocks.StrictMock<IBlogContext>();

            var blog = mocks.Stub<IBlog>();
            var author = mocks.PartialMock<Author>();
            author.Blogging = blog;

            Rhino.Mocks.SetupResult.For(context.GetBlog())
                .Return(blog);
            Rhino.Mocks.SetupResult.For(context.CurrentAuthor())
                .Return(author);

            mocks.ReplayAll();
        }

        [Specification]
        public void Attempting_to_publish()
        {
            var blog = context.GetBlog();
            var author = context.CurrentAuthor();

            story.WithScenario("publishing an entry")
                .Given("the blog under use", () => blog.ShouldNotBeNull())
                .And("the author is blogging", () => author.ShouldNotBeNull())
                .When("he attempts to publish an entry", () => author.Publish(entry))
                .Then("the blog engine is comunicated", () =>
                    blog.AssertWasCalled(b => b.SubmitEntry(entry)));
        }
    }
}


p>
using System.Collections.Generic;
using NBehave.Narrator.Framework;
using NBehave.Spec.NUnit;
using NUnit.Framework;
using Rhino.Mocks;
using MyCompany.Web.Blog.Specifications;
using Specification = NUnit.Framework.TestAttribute;

namespace MyCompany.Web.Blog.Tests
{
    [TestFixture]
    public class Blog_receiving_entries : SpecBase
    {
        private IBlogContext context;
        private Entry validEntry;
        private Entry entryWithInvalidTitle;
        private Entry entryWithInvalidSlug;
        private Entry entryWithInvalidContent;
        private List<Entry> invalidEntries;

        private Story story;
        private MockRepository mocks;

        [Story]
        public override void MainSetup()
        {
            base.MainSetup();
            PrepareContext();

            story = new Story("Receiving entries");

            story.AsA("Blog engine")
                .IWant("to receive entries")
                .SoThat("I can show them to a reader");
        }

        private void PrepareContext()
        {
            const string validTitle = "validTitle",
                validSlug = "validSlug", validContent = "validContent";
            const string intro = "intro";
            const List<Tag> tagsRelated = null;
            const string invalidTitle = "",
                invalidSlug = "", invalidContent = "";

            validEntry = new Entry(validTitle, validSlug,
                intro, validContent, tagsRelated);
            entryWithInvalidTitle = new Entry(invalidTitle,
                validSlug, intro, validContent, tagsRelated);
            entryWithInvalidSlug = new Entry(validTitle,
                invalidSlug, intro, validContent, tagsRelated);
            entryWithInvalidContent = new Entry(validTitle,
                validSlug, intro, invalidContent, tagsRelated);

            invalidEntries = new List<Entry>();
            invalidEntries.AddRange(new Entry[]
                                        {
                                            entryWithInvalidTitle,
                                            entryWithInvalidSlug,
                                            entryWithInvalidContent
                                        });

            mocks = new MockRepository();
            context = mocks.StrictMock<IBlogContext>();

            var blog = mocks.PartialMock<Blog>();
            var repository = mocks.Stub<IBlogRepository>();
            blog.Repository = repository;

            Rhino.Mocks.SetupResult.For(context.GetBlog())
                .Return(blog);
            mocks.ReplayAll();
        }

        [Specification]
        public void Receiving_valid_entries()
        {
            var blog = context.GetBlog();

            story.WithScenario("receiving a valid entry")
                .Given("the blog under use", () =>
                    blog.ShouldNotBeNull())
                .When("it receives a valid entry", () =>
                    blog.SubmitEntry(validEntry))
                .Then("the entry is accepted", () =>
                    blog.Entries.Contains(validEntry).ShouldBeTrue());
        }

        [Specification]
        public void Receiving_invalid_entries()
        {
            var blog = context.GetBlog();

            story.WithScenario("receiving an invalid entry")
                .Given("the blog under use", () =>
                    blog.ShouldNotBeNull())
                .When("it receives an invalid entry", () => { })
                .Then("the entry is rejected", () =>
                    invalidEntries.ForEach(invalidEntry =>
                        typeof(BlogException).ShouldBeThrownBy(() =>
                            blog.SubmitEntry(invalidEntry))));
        }
    }
}

Written by rafanoronha

February 28th, 2009 at 11:26 pm

Microsoft Certified Professional

without comments

No último dia de 2008 me tornei MCP (Microsoft Certified Professional).
Isto mesmo, foi em 31 de dezembro.

Eu explico.

Comprei  o voucher na promoção Second Shot.
Mas para utilizar a promoção eu precisava prestar o exame até o final de 2008.
Foi o que eu fiz.

Foram dezenas de horas de estudo, mas valeu a pena.
Nem precisei da segunda chance.

O exame 70-536 é apenas o primeiro passo para quem se interessar pelas certificações .NET da Microsoft.
Nos próximos meses pretendo dar continuidade à caminhada.

Se você está almejando se certificar também, aí vão algumas dicas:

  1. Se informe sobre as certificações no site da Microsoft. O que não falta é opção.
  2. Existem materiais publicados pela própria Microsoft, direcionados aos exames das certificações.
  3. Estude.

Para mim bastou o estudo focado no livro direcionado ao exame.

Um ponto interessante é que os exames exigem o domínio da tecnologia abordada, o que ajuda a aprofundar o seu conhecimento.

Boa sorte !

Ou melhor, bom estudo.

Written by rafanoronha

February 19th, 2009 at 11:53 pm

Posted in Sem categoria

Tagged with

NHibernate in Action – review

without comments

NHibernate in Action

NHibernate in Action

Li o livro há uns quinze ou vinte dias, deve ter levado umas 10 horas.

Achei bastante interessante a abordagem proposta. A todo momento são destacadas práticas recomendadas ou não quando usado o NHibernate.

NHibernate in Action cobre muita coisa no que diz respeito ao framework, o suficiente para servir de referência para quem trabalha ou visa trabalhar com ele.

É interessante que o leitor já possua conhecimento sobre o que é um ORM e principalmente, experiência com desenvolvimento .NET.

Após ler este livro você:

  1. Conhecerá os principais conceitos de persistência e mapeamento objeto/relacional;
  2. Entenderá porque este framework é muito bem visto por aqueles que utilizam-se da abordagem ORM no desenvolvimento de aplicações .NET;
  3. Entenderá a arquitetura do NHibernate, sabendo utilizar a API sem grandes problemas;
  4. Será capaz de traçar estratégias de mapeamento visando um aproveitamento eficaz de seu banco de dados, realizar mapeamentos complexos envolvendo por exemplo herança, conhecer o recurso de cache do NHibernate, entre outras coisas;
  5. Possivelmente se peguntará porque continuar fazendo acesso a dados na mão, caso você ainda o faça.

Concluindo, um livro de foco bem definido, capaz de iliustrar sua abordagem através de situações enfrentadas no dia-a-dia de desenvolvedores de software.

ORM é uma técnica que possibilita a redução de código de infra-estrutura escrito em uma aplicação, possibilitando à equipe de desenvolvimento manter o foco no negócio envolvido pelo software. Aplicações que aplicam técnicas e princípios da orientação a objetos possuem uma interação com sistemas de banco de dados relacionais pouco natural.

ORM tornou-se a ferramenta certa para aqueles que querem tratar mais de objetos (que representam o mundo real, através de estado e comportamento) e menos de dados relacionais.

Written by rafanoronha

February 15th, 2009 at 9:55 pm

Posted in Sem categoria

Tagged with

Desenhando um sistema de Blog

without comments

Há algumas semanas resolvi desenhar um sistema de Blog, para praticar alguns conceitos e tecnologias que venho adotando.

Dado o meu interesse por Domain-Driven Design, só há uma parte do sistema a ser projetada incialmente: o domínio.

Um blog é um sistema simples, em sua essência.
Algo como uma ferramenta online de publicação de textos.

Os textos são publicados por um autor, e a idéia é, obviamente, que eles sejam lidos por um leitor.
O leitor obtém os textos do blog de diversas maneiras. Pode estar procurando por posts recentes, de um determinado mês, pode se interessar por um post em especial, desejando ler o conteúdo completo.
Pode também procurar posts relacionados a determinado assunto.

Guiado por estas idéias, cheguei ao meu modelo inicial.
O modelo ainda não aborda muitas coisas, mas já contém o suficiente para dar um pontapé inicial no projeto:

Diagrama de classes

Diagrama de classes

Vale ressaltar que estou apenas levando em consideração a abordagem DDD, e que em nenhum momento esta abordagem implicará em limitar a minha criatividade ou comprometer a simplicidade de meu sistema.

Fica para posts futuros o aprofundamento do projeto, onde abordarei alguns aspectos da arquitetura que será utilizada e começarei a colocar a mão na massa.

Comentários e sugestões são muito bem vindos.

Written by rafanoronha

February 12th, 2009 at 10:33 pm

Posted in Sem categoria

Inauguração do blog

without comments

Este é o primeiro post de meu blog.

Meu nome é Rafael Noronha e sou desenvolvedor de sistemas, focado na tecnologia .NET, da Microsoft.
Você pode saber mais sobre mim aqui.

Discutirei neste blog assuntos relacionados a desenvolvimento de software

Para mim desenhar e codificar software assemelha-se mais a um trabalho artístico do que a uma atividade de engenharia, sendo esta constantemente utilizada em comparações impostas à minha atividade (possivelmente sua também).

Tenho como interesse otimizar as práticas realizadas por mim e aqueles que trabalham comigo. Buscar sempre melhores resultados, o que requer constante aperfeiçoamento e reciclamento. Espero carregar isto sempre comigo.

Espero que o blog viabilize a troca de idéias e experiências entre mim e profissionais atuantes no setor, servindo como ferramenta útil na luta pelos meus objetivos.

Feita a inauguração, em breve os primeiros posts oferecendo algum conteúdo de interesse (ou não !).

Já adianto que pretendo falar sobre processos de desenvolvimento, arquitetura, tecnologias, frameworks, etc.

Até lá.

Written by rafanoronha

February 9th, 2009 at 5:44 pm

Posted in Sem categoria