ラベル Spring の投稿を表示しています。 すべての投稿を表示
ラベル Spring の投稿を表示しています。 すべての投稿を表示

2013年1月9日水曜日

[Spring] Autowiredアノテーションを使っているクラスのユニットテスト

ちょっと確認のために試してみました。ソースは以下。
https://bitbucket.org/twopack/jsonrest/commits/e5353d883dffe31f99948a977b938c69
試したかったのは、 @Autowired でインジェクションしているクラスをJUnitで動かすにはどうするかです。

上記のソースで autoPerson を @Autowired してます。
決めうちでアクセスすると、autoPerson にアクセスして Micheal を返すようにしています。

テスト側で対応を行わない場合、テストを実行すると autoPerson で NullPointerException になります。JUnitで実行時には、 @Autowired でインジェクションが行われていないことが原因です。
対策のポイントは、以下のサイトを参照しました。



@Autowiredアノテーションを有効にする

1つ目のポイントは、JUnitのテストに @RunWith(SpringJUnit4ClassRunner.class) と @ContextConfiguration を記載して、 Spring の TestRunner で動くようにします。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class HomeControllerTest {
....
}

@ContextConfiguration を記載すると、クラスパス上の テストクラス名-context.xml を読み込んで設定します。
この中で、インジェクションするbeanを設定します。
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:beans="http://www.springframework.org/schema/beans"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  <beans:bean name="Person" class="jp.gr.java_conf.twopack.sample.jsonrest.Person"></beans:bean>
  </beans:beans>

テスト対象クラスのインスタンス化

1つ目のポイントでOK・・・かと思いきや、状況は変わりませんでした。
以下のようにアプリケーションコンテキストのメソッドを使ってテスト対象をインスタンス化する必要がありました。
@Autowired
ApplicationContext ctx;
 
HomeController sut;
  
@Before
public void setup() {
  sut = ctx.getAutowireCapableBeanFactory().createBean(HomeController.class);
}


ここまでで、テストも通るようになりました。

2012年12月11日火曜日

Springで提供されているモッククラス [Spring Framework Advent Calendar 2012 11日目 #jsug ]

Spring Framework Advent Calendar 2012の11日目です。
4巡目!間に合うか!(今23:50w)

Spring Frameworkではテスト用のモッククラスが提供されています。

一例としてMockHttpServletResponseを使ったテストケースが以下のようなものです。
@Test
public void testGetName_Tom() throws Exception {
  MockHttpServletResponse response = new MockHttpServletResponse();
  assertThat(sut.getName(response, 1), is("Tom"));
  assertThat(response.getStatus(), is(HttpServletResponse.SC_OK));
}

テスト対象のメソッドはコントローラーのもので、HttpServletResponseを引数に取っています。
@RequestMapping(value = "/person/name/{id}", method = RequestMethod.GET)
 public @ResponseBody String getName(HttpServletResponse response,
           @PathVariable int id) {
  if(id == 1) {
   return "Tom";
  }
  
  response.setStatus(HttpServletResponse.SC_NOT_FOUND);
  return "Not found.";
 }

HttpServletResponseのようなインスタンス化できないものについて、モックがあらかじめ用意されているのは非常に便利です。うまく使ってJunitを書きたいですね。

ソース全体はここでアップしています。ざっくりな内容なのはご容赦を。。。
https://bitbucket.org/twopack/jsonrest/commits/f7038c946113f538ffc4d5ee1cd729d5

2012年12月9日日曜日

Spring Frameworkについての情報 [Spring Framework Advent Calendar 2012 9日目 #jsug ]

Spring Framework Advent Calendar 2012の9日目です。
3巡目!繋ぎますw

Spring Frameworkについての情報ってどこにあるんだろう?
ということで、ぐぐったり、今まで見たものを覚えている範囲でまとめてみます。
Spring使いはじめて間もないので、そういう人向けになるといいなあ、と思っています。


ぐぐってみたもの


SpringSource.org


まずは、本家本元。チュートリアル、ニュース、開発者ブログなどがあります。
ニュースはRSSもあります。

日本Springユーザ会


日本Springユーザー会は、日本におけるSpringの情報交換を目的としたコミュニティです。
今回ぐぐって参加したのは、ないしょですw

Spring Framework - Wikipedia


日本語でまとまっているので、概略を掴むにはいいのでは?


今までにみたもの


Spring 3 MVC Hello World Example


Spring MVCのチュートリアルを書いてあるブログ。
なんとなくわかりやすそうだったので、これで写経してみました。

Spring 3.x - Spring MVC - Advanced topics


Spring3でのアノテーションについて、概略の説明がスライドになっています。

Spring 3.x - Spring MVC


こちらはSpring MVCの説明のスライド。

Spring 2.5:Spring MVCの新機能


Spring3の記事ではないですが、Spring MVCの機能を知るという意味では、わかりやすかったものです。
特に 暗黙のModel については、ソースはいろいろなところで見ましたが、どういうことかは、ここでやっとわかりました。


さいごに


もっと、いろいろな情報があると思います。特に日本語でも。
ここは必見というのがあれば、ぜひ教えてもらいたいなあ、と思います。

さて、無理矢理w繋いでみましたが、10日目は!?

2012年12月7日金曜日

MappingJacksonJsonViewを使ってみる [Spring Framework Advent Calendar 2012 7日目 #jsug ]

Spring Framework Advent Calendar 2012の7日目です。
2巡目!

これまた先日ブログで書いた二番煎じですが、Spring MVCでJSONを返すViewの例です。
ソースはここにあります。

サーブレットの設定

とりあえず、ソースです。
<beans:bean xmlns="http://www.springframework.org/schema/beans" 
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="json" value="application/json" />
    </map>
  </property>
  <property name="defaultViews">
    <list>
      <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView">
        <property name="prefixJson" value="true"/>
      </bean>
    </list>
  </property>
</beans:bean>

ContentNegotiatingViewResolver は、リクエストのAccept headerやファイル名をもとにViewを解決します。
map で指定しているのは、 key がファイルの拡張子、 value がコンテンツタイプです。
defaultViews は、ViewResolverのチェーンでViewが解決できない場合に使われるViewを指定します。
今回は、ここで MappingJacksonJsonView を指定することでViewとして使用するようにしています。


コントローラー

こちらは非常にやっつけなコードになっていますw
@RequestMapping(value = "/person/{id}", method = RequestMethod.GET)
public @ResponseBody Person getPerson(@PathVariable int id, Model model) {
  Person person = new Person();
  person.setId(id);
  person.setName("Tom");
  return person;
}

@ResponseBody をつけてPOJOを返すことでレスポンスはJSONになります。
以下のサイトで詳しく説明されています。 #私が今書いている意味って(ry



上のコードでは、以下のようなJSONが出力されます。
{"name":"Tom","id":1}

最後に

今回は MappingJacksonJsonView でしたが、他にもSpringで使えるViewはあるので、それらをうまく使うといろいろなことを簡単に行えそうですね。

8日目は @mike_neck さん、よろしくお願いします!

2012年12月5日水曜日

Spring + Thymeleafでデザインの分離を進める(のとっかかり) [Spring Framework Advent Calendar 2012 5日目 #jsug ]

Spring Framework Advent Calendar 2012の5日目です。

とっかかりということで、Hello Worldです。
以前のブログでもこの組み合わせについて書いていますが、導入を含めて少しまとめた形で書いていこうと思います。
以下の環境で確認しています。

  • Max OS X 10.7.5
  • Eclipse JavaEE Juno SR1
  • JDK 1.6
  • Spring MVC 3.1.1.RELEASE
  • Thymeleaf 2.0.13


プロジェクト作成


Spring MVCテンプレートからのプロジェクト作成

Spring MVCのテンプレートからプロジェクトを作ります。
Eclipseで、
New -> Other -> Spring Template Project -> Spring MVC Project
から作成します。ウィザードを完了した状態で私の環境ではプロジェクトにエラーがある状態でした。これらは以下を実行して解消しました。
  • Run -> Run As -> Maven Build で Goals に compile を指定して実行する。
  • プロジェクトで右クリックして Maven -> Update Project を選択する。

Thymeleafのライブラリを依存関係に追加

Spring 3.xでThymeleafを使う場合には、 thymeleaf-spring3 を使用します。
使用するには、Mavenのpom.xmlに以下を追加します。
<dependency>
 <groupId>org.thymeleaf</groupId>
 <artifactId>thymeleaf-spring3</artifactId>
 <version>2.0.13</version>
</dependency>

テンプレートエンジンの変更

Spring MVCのテンプレートで作成されるプロジェクトは、JSPのテンプレートエンジンを使ったHello Worldです。これをThymeleafのテンプレートエンジンに差し替えます。

サーブレットの設定

サーブレットの設定ファイルを以下のように書き換えます。
<beans:bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
 <beans:property name="prefix" value="/WEB-INF/templates/" />  
 <beans:property name="suffix" value=".html" />
 <beans:property name="templateMode" value="HTML5" />
</beans:bean>
 
<beans:bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
 <beans:property name="templateResolver" ref="templateResolver" />
</beans:bean>

<beans:bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
 <beans:property name="templateEngine" ref="templateEngine" />
</beans:bean>

templateResolver の property の意味合いは以下の通り。
  • prefix と suffix は、Viewテンプレートの検索先を指定します。この場合は、 /WEB-INF/templates/*.html からViewテンプレートを探します。
  • templateMode は、Viewテンプレートで使用する形式を指定します。
  • 指定できる形式は、ここを参照してください。

テンプレートの置き換え

Hello WorldのJSPのテンプレートからThymeleafのテンプレートに置き換えます。
サーブレットの設定で書いた通り、 /WEB-INF/templates を作成してベースにするHTMLファイルを置きます。
今回は、 home.jsp を home.html とリネームして、JSPテンプレートのプロジェクトを実行した際に生成されたHTMLを中身としました。
この時点では、動的に出力は変化しません。

動的な出力

JSPテンプレートのHello Worldでは、現在時刻を表示するようになっていました。
同じことをThymeleafテンプレートでもやってみます。

データの作成

コントローラーの home メソッドは以下のように書き換えます。
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
 logger.info("Welcome home! The client locale is {}.", locale);
 
 Date date = new Date();
 DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
 
 String formattedDate = dateFormat.format(date);
 
 String message = "  The time on the server is " + formattedDate + ". ";
 
 model.addAttribute("serverTimeMessage", message );
 
 return "home";
}

JSPからの変更点はL10〜12です。
Thymeleafでは後述するようにHTMLのタグ属性で置換対象を指定します。このため、タグの中身全体を message で作成して serverTimeMessage 属性でViewに渡しています。

テンプレートでのデータの受け取り

テンプレートを以下のように変更して、コントローラーからの serverTimeMessage を出力に反映します。
<P th:text="${serverTimeMessage}">  The time on the server is 2012/12/05 10:01:10 JST. </P>

th:text でコントローラーで設定した serverTimeMessage を指定しています。実行時にタグの中身が置き換わります。
th:text と属性で指定することで、タグの中身を想定する内容でHTMLに記述する事ができ、HTMLのみをブラウザで表示した場合にも、実行時と同様の表示が可能になります。これによって、デザインと実装の分離が進む事がThymeleafの利点となります。


まとめ

ここまでで実行するとJSPテンプレートと同様に現在時刻を表示するHello Worldができました。
Thymeleafのテンプレートで指定できる属性は、 The Standard Dialect としてTurtorialに記載があります。ここではごく簡単な例でしたが、他にもいろいろな指定が可能です。
また、Springと合わせた使い方についても別のTurtorialとしてまとまっています。今回はこれを参考にしています。

最後に、ソースについてはここで公開しています。セクションの単位でコミットしました。


6日目はKouhei Tokiさんです!よろしくお願いします!

2012年11月27日火曜日

Spring3 MVCでJSONを返すRESTもどき2

今回は電車の中でやってます。
というわけで、HTTPステータスコードを返す&Junitでのテストです。

ステータスコードの設定

ステータスコードの設定は、コントローラーのメソッドに対して@ResponseStatusアノテーションでできる。
ステータスコード自体は、HttpStatus.*を使う。

POSTで201(Created)を返すコードを追加した。
試してみるのにrest-clientを使用した。これは便利。

作成したコードは以下でコミット。
https://bitbucket.org/twopack/jsonrest/changeset/c903d770a37754f04ddd0dccaa83971e

RESTをJUnitでテストする

restfuseを使用。
前回のpom.xmlでJUnitのバージョンを4.6としていたせいで、@Ruleアノテーションが使えずはまった。。
他はrestfuseのトップにあるとおりでできた。
JSONについては、JacksonのObjectMapperを使ってMapにしてから比較するようにした。

作成したコードは以下でコミット。
https://bitbucket.org/twopack/jsonrest/changeset/1e233fb47e482b80fc3bf69156c04e76

2012年11月26日月曜日

Spring3 MVCでJSONを返すRESTもどき

Eclipseでプロジェクトを作るところから開始。
環境は、Mac OS X 10.7.5 + Eclipse Juno + Spring Tool Suite。

プロジェクトの作成

  1. File -> New -> Other -> Spring Template Project -> Spring MVC Project
    の順で選択していく。Importの確認メッセージがでたらYesで継続する。
  2. Project NameとPackage Nameを入力してFinish。
  3. junitのdependencyでエラーになったため、pom.xmlでバージョンを4.6に変更。
  4. Debug As -> Debug on Server でできたプロジェクトを実行する。
    今回はTomcat6で実行した。
  5. ここまでで、Hello Worldが表示される。

JSONを返す処理

Spring MVC Tip: Returning JSON from a Spring Controller
Spring MVCでJSONデータを返すための手順
を参考にして処理を作成した。
  1. pom.xmlにjackson-mapper-aslの依存関係を追加。
  2. servlet-context.xmlでMappingJacksonJsonViewを使うように内容を修正。
  3. コントローラーにGETに対する処理を追加。
    @RequestBody, @RequestMapping, @PathVariableのアノテーションを利用。
    Personクラスを返した結果として、JSONに変換が行われる。

とりあえず、ここまで。
ソースは以下にアップ。
https://bitbucket.org/twopack/jsonrest/changeset/5c0ddd8400ba24e9fbdd976dad288567cc653f94

2012年11月20日火曜日

Spring 3.0 + Thymeleafを試してみる(1)

まずはSpring 3.0のチュートリアルを探してきて写経しました。
Spring 3 Hello World Example

このチュートリアルでViewはJSPです。ここにThymeleafでのViewを追加します。
Thymeleafのチュートリアルを見ながら、テキストを置き換えるだけの簡単なコードを書きました。
TUTORIAL: THYMELEAF + SPRING 3
また、チュートリアルのサンプルソースがGithubで公開されています。

はまったところは以下。

  • resourcesの配置先をsrcの下に置く必要があった。
  • servletのxmlをJSPのものと分けたが、コントローラーも分けてあげる必要があった。

あとはチュートリアル通りでできました。
今のところはただのテキスト置き換えのみなので、他の構文も試してみたいと思います。

写経からThymeleaf用の追加までのソースは以下です。
https://bitbucket.org/twopack/helloworldspring3

RedmineプラグインをGitHub Actionsでテストする

Redmine Advent Calendar 2019 の Qiita で書きました。追っかけで もう一つ 。 Travis-CIで行っていたRedmineプラグインのCIを、GitHub Actionsに変更したものです。 GitHub Actionsをやってみようという...