Search on the blog

2015年11月21日土曜日

Spockでテストする

Spcokとは?
  • テスティングフレームワーク
  • Java、Groovyのアプリケーションのテストができる
  • テストはGroovyで書く

導入方法
build.gradleに以下を追記する。
cglib:cglib-nodep:2.2というライブラリを入れておくとインターフェースを作っていないクラスの場合でもモックオブジェクトが作れて便利。

apply plugin: 'java'
+apply plugin: 'groovy'
apply plugin: 'eclipse'

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.projectlombok:lombok:1.16.6'
    compile 'io.netty:netty-all:4.1.0.Beta1'
    testCompile 'junit:junit:4.12'
+    testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
+    testCompile 'cglib:cglib-nodep:2.2'
}

サンプル1
まずは簡単なやつから。
package com.kenjih.spoc;

public class FizzBuzz {
    public String calc(int x) {
        if (x % 15 == 0)
            return "Fizz Buzz";
        if (x % 3 == 0)
            return "Fizz";
        if (x % 5 == 0)
            return "Buzz";
        return String.valueOf(x);
    }
}
上のFizz Buzzをテストするコードを書いてみる。
package com.kenjih.spoc

import spock.lang.Specification;

class FizzBuzzTest extends Specification {

    def test() {
        setup:
        FizzBuzz f = new FizzBuzz()
        
        expect:
        f.calc(x) == ret
        
        where:
        x      |  ret
        3      |  "Fizz"
        10    |  "Buzz"
        15    |  "Fizz Buzz"
        0      |  "Fizz Buzz"
        101 |  "101"
    }
}

サンプル2
もうちょっと複雑なテストを書いてみる。
ServiceからDaoを呼んでいるときに、Daoの戻り値を恣意的に変えたり、Daoのメソッドが呼ばれた回数をカウントしたりできる。
package com.kenjih.spoc;

import java.util.HashMap;
import java.util.Map;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class UserService {
    
    @NonNull
    final UserDao userdao;
    
    public boolean login(String uid, String pass) {
        if (uid == null || pass == null)
            return false;
        
        Map<String, Object> cond = new HashMap<String, Object>();
        cond.put("uid", uid);
        cond.put("pass", pass);
        
        return userdao.count(cond) == 1;
    }
}

メソッド名には日本語も使えて便利。。
package com.kenjih.spoc

import spock.lang.Specification;

class UserServiceTest extends Specification {
    def "uidとpassが正しい場合のみログイン成功する"() {
        setup:
        UserDao userDao = Mock()
        userDao.count(_) >> rowCount
        UserService userService = new UserService(userDao)
        
        expect:
        userService.login(uid, pass) == res

        where:
        uid       | pass      | rowCount | res 
        null      | "1234" | 1               | false
        "taro" | null        | 1               | false
        "taro" | "1234" | 0               | false
        "taro" | "1234" | 1               | true
    }
    
    def "uidかpassがnullのときはDBアクセスしない"() {
        setup:
        UserDao userDao = Mock()
        UserService userService = new UserService(userDao)
        
        when:
        userService.login(null, "abcd")
        then:
        0 * userDao.count(_)
        
        when:
        userService.login("jiro", null)
        then:
        0 * userDao.count(_)

        when:
        userService.login("yukiko", "xyz")
        then:
        1 * userDao.count(_)
    }
}

0 件のコメント:

コメントを投稿