Posted at

JMockitの使い方

More than 5 years have passed since last update.

テストクラスを書くときに使いそうなので事前に調査した。

調べたのは下記の通り


  • Springを使ってるのでDIしている箇所がモックにできるか

  • staticメソッドの戻りもモックにできるか

  • new Date()...の戻り値もモックにできるか

結論:できた。

これ1つで全部まかなえたのは結構大きいかもしれない。できないことはなんだろうか??


テストクラス

package com.hachiyae.jmockit;

import mockit.Expectations;
import mockit.Mock;
import mockit.MockUp;
import org.junit.Test;

import java.util.Calendar;
import java.util.Date;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

public class TesterServiceTest {
private TesterService tester = new TesterService();

@Test
public void testSayHello() throws Exception {
String message = tester.sayHello("user1");
assertThat(message, is("Hello user1"));
}

// // これでもOK
// @Mocked
// private CurrentDateFactory currentDateFactory;

// 引数でもいいよ
@Test
public void testSayCurrentDate(final CurrentDateFactory currentDateFactory) throws Exception {
new Expectations() {
// ここにつけてもいいよ
// CurrentDateFactory currentDateFactory;
{
setField(tester, currentDateFactory);
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(2014, 0, 1);
// 直後にresultに値を入れることでモックの戻り値を定義
// timesは回数(1の時は省略
currentDateFactory.getCurrentDate(); result = calendar.getTime(); times = 1;
}
};
String message = tester.sayCurrentDate();
assertThat(message, is("current date is 2014/01/01"));
}

@Test
public void testSayCurrentTime() throws Exception {
// static method
new Expectations() {
// 無駄にモックオブジェクトインスタンスを生成しない
final TestUtils testUtils = null;

{
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(2014, 0, 1, 1, 2, 3);
testUtils.getCurrentDate(); result = calendar.getTime();
}
};
String message = tester.sayCurrentTime();
assertThat(message, is("current time is 01:02:03"));
}

@Test
@SuppressWarnings({"unused", "deprecation"})
public void testSayCurrentYear() throws Exception {
new MockUp<System>() {
@Mock
public long currentTimeMillis() {
return new Date(110, 0, 1).getTime();
}
};
String message = tester.sayCurrentYear();
assertThat(message, is("current year is 2010"));
}
}



テスト対象クラス

package com.hachiyae.jmockit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;

@Service
public class TesterService {
@Autowired
private CurrentDateFactory currentDateFactory;

public String sayHello(String userName) {
return "Hello " + userName;
}

public String sayCurrentDate() {
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
return "current date is " + format.format(currentDateFactory.getCurrentDate());
}

public String sayCurrentTime() {
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
return "current time is " + format.format(TestUtils.getCurrentDate());
}

public String sayCurrentYear(){
SimpleDateFormat format = new SimpleDateFormat("yyyy");
Date date = new Date();
return "current year is " + format.format(date);
}
}



テスト対象クラスから呼ばれるService

package com.hachiyae.jmockit;

import org.springframework.stereotype.Service;

import java.util.Date;

@Service
public class CurrentDateFactory {
public Date getCurrentDate(){
return new Date();
}
}



テスト対象クラスから呼ばれるstatic

package com.hachiyae.jmockit;

import java.util.Date;

public class TestUtils {
public static Date getCurrentDate (){
return new Date();
}
}


参考URL: