Thursday, March 31, 2011

Unit Testing with Scala

Last month, I promised myself to start to write unit tests with Scala instead of Java. I have disregarded this promise, like so many others like it, until this very day. My ignorance towards my pledge was not because of lack of code to test, anything but. However my scala skills are not advanced enough to tackle complex spring controller integration testing with mocks and tacky business logic of my hobby projects nor is the Eclipse IDE at work smart enough to understand mix language development. So, unfortunately I had to rely to a trivial scala development exercise, with but a little real practical use.

To kick start scala testing practice you will need:

  1. get some code to test
  2. set up a tools for the art
My beloved company Houston Inc. holds frequent coding dojos, which in a OS fashion are made public for anyone to access [2]. I grabbed the source code for the dojos from github [1] and rewrote the unit tests using ScalaTest [3].

I downloaded the IntelliJ [4] and installed the scala plug-in [5].
I create a maven project with the scala-archetype. After the project was created I updated the pom.xml file with the ScalaTest dependency.



  4.0.0
  com.houston.tdd
  ScalaTDD
  1.0
  
    2.8.0
  
  
    
        org.scalatest
        scalatest
        1.3
    
    
      org.scala-lang
      scala-library
      ${scala.version}
    
    
      junit
      junit
      4.8.1
      test
    
  
  
    src/main/scala
    src/test/scala
    
      
        org.scala-tools
        maven-scala-plugin
        
          
            
              compile
              testCompile
            
          
        
        
          ${scala.version}
        
      
      
        org.apache.maven.plugins
        maven-eclipse-plugin
        
          true
          
            ch.epfl.lamp.sdt.core.scalabuilder
          
          
            ch.epfl.lamp.sdt.core.scalanature
          
          
            org.eclipse.jdt.launching.JRE_CONTAINER
            ch.epfl.lamp.sdt.launching.SCALA_CONTAINER
          
        
      
    
  
  
    
      
        org.scala-tools
        maven-scala-plugin
        
          ${scala.version}
        
      
    
  


I downloaded the source code from the github [1] and created a small main class to make sure code executes.

package com.houston.tdd;

/**
 * Execution class for Cashier.java object
 * Date: 3/30/11
 * @author Heikki Leskinen
 */
public class App {

    public static void main(String[] args){
        Cashier cashier = new Cashier();

        cashier.add(Product.BANANA);
        cashier.add(Product.BANANA);

        System.out.println(Double.toString(cashier.countTotalPrice()));
        cashier.add(Product.BANANA);

        System.out.println(Double.toString(cashier.countTotalPrice()));

    }

}

I created the unit tests by extending the JUnitSuite trait to ensure, I end up with a valid JUnit class.

package com.houston.tdd;

import org.scalatest.junit.JUnitSuite
import org.junit.Assert._
import org.junit.Test

class CashierTestSuite extends JUnitSuite {

  val cashier = new Cashier();

  def addProducts(p: Product, x: Int) = {
      for (i <- 1 to x) cashier.add(p);
  }

  @Test def testCountTotalPriceOfEmptyBasket() {
      assertEquals(0.0, cashier.countTotalPrice())
  }

  @Test def testCountTotalPriceOfOneApple() {
      cashier.add(Product.APPLE)
      assertEquals(1.0, cashier.countTotalPrice())
  }

  @Test def testCountTotalPriceOfTwoApples() {
      cashier.add(Product.APPLE);
      cashier.add(Product.APPLE);
      assertEquals(2.0, cashier.countTotalPrice());
  }

  @Test def testCountTotalPriceOfAppleAndOrange() {
      cashier.add(Product.APPLE);
      cashier.add(Product.ORANGE);
      assertEquals(1.5, cashier.countTotalPrice());
  }

  @Test def testCountTotalPriceOfTwoBananas() {
      cashier.add(Product.BANANA);
      cashier.add(Product.BANANA);
      assertEquals(1.4, cashier.countTotalPrice());
  }

  @Test def testCountTotalPriceOfTenOranges() {
      addProducts(Product.ORANGE, 10);
      assertEquals(4.0, cashier.countTotalPrice());
  }


  @Test def testCountTotalPriceOfTenApples() {
      addProducts(Product.APPLE, 5);
      assertEquals(4.0, cashier.countTotalPrice());
  }


  @Test def testCountTotalPriceOfTenBananas() {
      addProducts(Product.BANANA, 3);
      assertEquals(2.0, cashier.countTotalPrice());
  }

  @Test def testCountTotalPriceOfTenMelons() {
      addProducts(Product.MELON, 10);
      assertEquals(17.0, cashier.countTotalPrice());
  }

}

Test can be executed with either ScalaTest or JUnit, since I am extending a org.scalatest.junit.JUnitSuite.

First steps completed.

2 comments:

  1. Don't see much of a point of writing the unit tests in Scala in your case? Why bother?

    ReplyDelete
  2. Well, It's a great method of learning Scala syntax and basic functionality as well as BDD and SBT.

    ReplyDelete