Ao criar um novo projeto rails é criado juntamente com o projeto um arquivo database.yml parecido com este:

development:
  adapter: mysql
  encoding: utf8
  database: project_development
  username: root
  password: password
  socket: /var/run/mysqld/mysqld.sock

test:
  adapter: mysql
  encoding: utf8
  database: project_test
  username: root
  password: password
  socket: /var/run/mysqld/mysqld.sock

production:
  adapter: mysql
  encoding: utf8
  database: project_production
  username: root
  password: password
  socket: /var/run/mysqld/mysqld.sock

Mas, como sempre ouvimos, um dos conceitos base do RoR é o DRY (Don’t Repeat Yourself – Não repita a si mesmo). E como podemos ver neste arquivo existem diversas linhas duplicadas.

De uma forma geral as bases de dados de desenvolvimento, produção e teste residem na mesma máquina e portanto temos algumas linhas que sempre iremos repetir:

  adapter: mysql
  encoding: utf8
  username: root
  password: password
  socket: /var/run/mysqld/mysqld.sock

Googlando não é nada difícil encontrar o seguinte modelo de database.yml conhecido como “DRY database.yml”:

login: &login
  adapter: mysql
  username: root
  password: password
  socket: /var/run/mysqld/mysqld.sock

development:
  <<: *login
  database: project_development

test:
  <<: *login
  database: project_test

production:
  <<: *login
  database: project_production

Mas, concordemos que ainda existe uma certa duplicação de código. Então lá vai a versão DRier do database.yml:

login: &login
  adapter: mysql
  username: root
  password: password
  host: localhost

<% ["development", "test", "production"].each do |environment| %>
<%= environment %>:
  <<: *login
  database: biblemarks_<%= environment %>
<% end %>
Advertisements

If you have created an Abstract Class you may want to test its non abstract methods. But there is one problem: we can’t instantiate abstract classes.

There are two ways to test their non abstract methods:

Testing Abstract Classes Through Their Children’s

Suppose we have the following abstract class named Person:

public abstract class Person {
    private String firstName;
    private String lastName;

    public abstract void doAnything();
    public String getFullName(){
        return firstName + " " + lastName;
    }
    // Getters and setters here...
}

And a Boss class that extends Person:

public class Boss extends Person{
    @Override
    public void doAnything() {
        System.out.println("Do anything...");
    }
}

And you want to test the Person.getFullName() method. So you must create the test below:

public class PersonTest {
    Person person;
    @Before
    public void setUp() {
        person = new Boss();
        person.setFirstName("Anderson");
        person.setLastName("Dias");
    }
    @Test
    public void getFullName(){
        assertEquals("Anderson Dias", person.getFullName());
    }
}

On this first case, it will work fine and the test will pass no matter. But there is a problem, because it’s been assumed that the Boss class will never override the getFullName() method. If the Boss class changes, the test will fail.

public class Boss extends Person {
    @Override
    public String getFullName(){
        return "Mr. " + super.getFullName();
    }
    @Override
    public void doAnything() {
        System.out.println("Do anything...");
    }
}

So, what to do? Let’s see another way to test Abstract Classes.

Creating Mock Implementations for Abstract Classes

There is a simple way to test them. You can create a mock class that simulates the implementation of an abstract class. You will guarantee that the non abstract methods will be the same of the parent abstract class.

Let’s see a sample Mock implementation:

public class MockPerson extends Person {
    @Override
    public void doAnything() { }
}

Notice that you don’t have to test the Person abstract class methods right now. So you don’t have to implement the doAnything() method body on the Mock implementation.

And our Test Case will be:

public class PersonTest {
    Person person;
    @Before
    public void setUp() {
        person = new MockPerson();
        person.setFirstName("Anderson");
        person.setLastName("Dias");
    }
    @Test
    public void getFullName(){
        assertEquals("Anderson Dias", person.getFullName());
    }
}

That’s a simple way to test abstract methods.

Of course there are some specifics cases that Mock Objects don’t solve, in those cases you will need to test using the first strategy.

public abstract class Person {
    private String firstName;
    private String lastName;

    public abstract void doAnything();
    public String getFullName(){
        this.doAnything();
        return firstName + " " + lastName;
    }
    // Getters and setters here...
}

In this case our non abstract method ( Person.getFullName() ) calls the abstract method ( Person.doAnything() ), and the implementation of Person.doAnything() method may be decisive for the Person.getFullName() return. So, the only way to test it will be by the Person children classes.

I hope you enjoy it.

Thanks to Raquel Carsi for help me to write this post.


When I am trying to use rubygems on Ubuntu 7.10 I took this error:

"rubygems/custom_require.rb:27:in `gem_original_require':
no such file to load -- sources (LoadError)"

This error occurs when GEM_HOME system variable is unset. To solve that first check your gems directory:

# locale will find occurrences of gems on the system
# look for the one that points to gems home directory
locate gems

The default path for rubygems ( ruby version 1.8 ) is “/var/lib/gems/1.8”.

So now create the GEM_HOME variable:

# export GEM_HOME="path_to_gems"
export GEM_HOME="/var/lib/gems/1.8/"

And rubygems will work well.


Welcome to ExtendsMyMind, a blog about programming skills and software development were I’ll share all the things that I’m learning and creating.

Lets start a good time!