SlideShare uma empresa Scribd logo
1 de 14
Baixar para ler offline
Chapter 26.
 Design for
 Testability
  Patterns
Dependency Injection
Dependency Injection
●   SUT をどう設計すれば、ランタイムに依存オブジェ
    クトを差し替えられるだろうか?
    ●   クライアントが SUT に対して依存オブジェクトを提供す
        れば良い
    ●   テストする際には、 SUT を依存から独立してテストでき
        るのが望ましいが、依存クラス名などがハードコードさ
        れていると難しい
    ●   Dependency Injection は、 SUT に対する依存オブ
        ジェクトをテスト時に差し替えるのに使える
How It Works
●   クライアントコードやシステムの設定部(ファイル/
    コード)で、 SUT が実行時に依存するオブジェクトを
    渡せるようにする
●   この設計のポイントは、 依存が “front door” から
    渡せるようになっているところ
    ●   つまり、「依存を渡す」ということも SUT の API の一部
        になる
    ●   依存の渡し方は、メソッドの引数、コンストラクタ、 setter
        などがある。
When to Use It
●   まずは、テスト時に DOC を Test Double に差し替
    えるときに使う
    ●   Static binding は依存クラス名を SUT に直接書いてし
        まうことで、採れる手段を大幅に狭めてしまう
    ●   Dynamic binding は依存クラスの解決を実行時まで遅
        延することで、柔軟さを得ることができる
●   Dependency Injection(DI) はコードをスクラッチ
    から設計する際には良い手段となる
    ●   特に TDD で設計している場合には、 DOC を Test
        Double で差し替えたくなるので、自然と DI が必要にな
        る
Implementation Notes(1)
●   二つの解決すべき問題がある
    ●   Test Double をどんな DOC の場合にも使えるように
        する必要がある。これは静的型付け言語の場合には、
        Test Double をいかにも DOC のように(型を矛盾させ
        ること無く)渡せなければならないことを意味する
    ●   SUT に Test Double を渡す手段を提供しなければな
        らない
Implementation Notes(2)
●   型の互換性
    ●   (特に静的型付け言語で) DI を実現するには、 DOC と
        Test Double が Type Compatible でなければならな
        い
    ●   静的型付け言語では、 DOC と Test Double が共通の
        interface を実装していること
    ●   動的型付け言語では、 DOC と Test Double が同じ
        signature (メソッド名など) を持っていること
    ●   既存のコードに対して DI パターンを導入するには、まず
        DOC に対して「インターフェイスの抽出」を行い、その抽
        出された interface に対して Test Double を書けば良
        い
Implementation Notes(3)
●   Test Double の渡し方
    ●   さまざまなやり方があるが、名前/型のハードコードを止
        め、実行時まで解決を遅らせるという基本は変わらない
        –   Parameter Injection
             ●   使いたいメソッドの引数として DOC も渡す
        –   Constructor Injection
             ●   SUT 構築時に DOC を渡す
        –   Setter Injection
             ●   どこかのタイミングで setter 経由で DOC を SUT に渡す
    ●   IoC フレームワーク (DI コンテナ) を使うと、 DI の仕組
        みの実装自体も作らずに済み、つまり SUT や DOC は
        DI の実装に対して非依存になり、使いまわしが効くよう
        になる
Motivating Example
// リファクタリング前のコード
public void testDisplayCurrentTime_AtMidnight() {
  //fixture setup
  TimeDisplay sut = new TimeDisplay();
  //exercise SUT
  String result = sut.getCurrentTimeAsHtmlFragment();
  //verify direct output
  String expectedTimeString =
                   
    "<span class="tinyBoldText">Midnight</span>";
  assertEquals( expectedTimeString, result);
}



public String getCurrentTimeAsHtmlFragment() {
  Calendar currentTime;
  try {
     currentTime = new DefaultTimeProvider().getTime();
  } catch (Exception e) {
     return e.getMessage();
  }
  // etc.
}
Parameter Injection
// テストコード
public void testDisplayCurrentTime_AtMidnight_PI() {
  //Fixture setup
  //Test Double instantiation
  TimeProvider tpStub = new MidnightTimeProvider();
  //Instantiate SUT
  TimeDisplay sut = new TimeDisplay();
  //Exercise SUT using Test Double
  String result = sut.getCurrentTimeAsHtmlFragment(tpStub);
                   
  //Verify outcome
  String expectedTimeString =
    "<span class="tinyBoldText">Midnight</span>";
  assertEquals("Midnight", expectedTimeString, result);
}

//プロダクトコード
public String getCurrentTimeAsHtmlFragment(TimeProvider timeProviderArg) {
  Calendar currentTime;
  try {
     currentTime = timeProviderArg.getTime();
  } catch (Exception e) {
     return e.getMessage();
  }
  // etc.
}
Constructor Injection
// テストコード
public void testDisplayCurrentTime_AtMidnight_CI() throws Exception {
  //Fixture setup
  //Test Double instantiation
  TimeProvider tpStub = new MidnightTimeProvider();
  //Instantiate SUT injecting Test Double
  TimeDisplay sut = new TimeDisplay(tpStub);
  //Exercise SUT
  String expectedTimeString =
                  
    "<span class="tinyBoldText">12:01 AM</span>";
  //Verify outcome
  assertEquals("12:01 AM",
          expectedTimeString,
          sut.getCurrentTimeAsHtmlFragment());
}

//プロダクトコード
public class TimeDisplay {
    private TimeProvider timeProvider;
    public TimeDisplay() { //backwards compatible constructor
      timeProvider = new DefaultTimeProvider();
    }
    public TimeDisplay(TimeProvider timeProvider) { //new constructor
      this.timeProvider = timeProvider;
    }
...
}
Setter Injection(1)
// テストコード
public void testDisplayCurrentTime_AtMidnight_SI()
  throws Exception {
  //Fixture setup
  //Test Double instantiation
  TimeProvider tpStub = new MidnightTimeProvider();
  //Instantiate SUT
  TimeDisplay sut = new TimeDisplay();
  //Test Double installation
                   
  sut.setTimeProvider(tpStub);
  //Exercise SUT
  String result = sut.getCurrentTimeAsHtmlFragment();
  //Verify outcome
  String expectedTimeString =
    "<span class="tinyBoldText">Midnight</span>";
  assertEquals("Midnight", expectedTimeString, result);
}
Setter Injection(2)
// プロダクトコード
public class TimeDisplay {
    private TimeProvider timeProvider;
    public TimeDisplay() {
      timeProvider = new DefaultTimeProvider();
    }
    public void setTimeProvider(TimeProvider provider) {
      this.timeProvider = provider;
    }
    public String   
                  getCurrentTimeAsHtmlFragment() throws TimeProviderEx {
      Calendar currentTime;
      try {
         currentTime = getTimeProvider().getTime();
      } catch (Exception e) {
         return e.getMessage();
      }
      // etc.
    }
...
}
ご清聴
 ありがとう
ございました

Mais conteúdo relacionado

Mais procurados

xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19Takuto Wada
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うKenji Kazumura
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にTaku Miyakawa
 
テストを書こう、Unity編
テストを書こう、Unity編テストを書こう、Unity編
テストを書こう、Unity編Hiroto Imoto
 
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築kimukou_26 Kimukou
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてkimukou_26 Kimukou
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsYoshifumi Kawai
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyYasuharu Nakano
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackTakahiro Yoshimura
 
about DEXCS for OpenFOAM
about DEXCS for OpenFOAMabout DEXCS for OpenFOAM
about DEXCS for OpenFOAMEtsuji Nomura
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)Takuya Tsuchida
 
xUnit Test Patterns - Chapter16
xUnit Test Patterns - Chapter16xUnit Test Patterns - Chapter16
xUnit Test Patterns - Chapter16Takuto Wada
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!Akihiro Nishimura
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1Uehara Junji
 
Free cad 0.19.2 and cfdof (Japanese Ver.)
Free cad 0.19.2 and cfdof (Japanese Ver.)Free cad 0.19.2 and cfdof (Japanese Ver.)
Free cad 0.19.2 and cfdof (Japanese Ver.)YohichiShiina
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテストushiboy
 

Mais procurados (20)

xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19
 
Javaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使うJavaでトランザクショナルメモリを使う
Javaでトランザクショナルメモリを使う
 
Java SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心にJava SE 9の紹介: モジュール・システムを中心に
Java SE 9の紹介: モジュール・システムを中心に
 
テストを書こう、Unity編
テストを書こう、Unity編テストを書こう、Unity編
テストを書こう、Unity編
 
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
Eclipse ADTとAndroidStudio両方で動かせる開発環境構築
 
qmake入門
qmake入門qmake入門
qmake入門
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用について
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
Java開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovyJava開発の強力な相棒として今すぐ使えるGroovy
Java開発の強力な相棒として今すぐ使えるGroovy
 
GroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hackGroovyなAndroidテスト #atest_hack
GroovyなAndroidテスト #atest_hack
 
123 Dexcs2021
123 Dexcs2021123 Dexcs2021
123 Dexcs2021
 
123 dexcs2019
123 dexcs2019123 dexcs2019
123 dexcs2019
 
about DEXCS for OpenFOAM
about DEXCS for OpenFOAMabout DEXCS for OpenFOAM
about DEXCS for OpenFOAM
 
あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)あんなテスト、こんなテスト(this and that about testing)
あんなテスト、こんなテスト(this and that about testing)
 
xUnit Test Patterns - Chapter16
xUnit Test Patterns - Chapter16xUnit Test Patterns - Chapter16
xUnit Test Patterns - Chapter16
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1New features of Groovy 2.0 and 2.1
New features of Groovy 2.0 and 2.1
 
Free cad 0.19.2 and cfdof (Japanese Ver.)
Free cad 0.19.2 and cfdof (Japanese Ver.)Free cad 0.19.2 and cfdof (Japanese Ver.)
Free cad 0.19.2 and cfdof (Japanese Ver.)
 
ゼロから始めたE2Eテスト
ゼロから始めたE2Eテストゼロから始めたE2Eテスト
ゼロから始めたE2Eテスト
 

Destaque

組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術Takuto Wada
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassTakuto Wada
 
フィーチャモデルの描き方
フィーチャモデルの描き方フィーチャモデルの描き方
フィーチャモデルの描き方H Iseri
 
fluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギングfluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギングYuichi Tateno
 
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015Yahoo!デベロッパーネットワーク
 

Destaque (6)

組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術組織にテストを書く文化を根付かせる戦略と戦術
組織にテストを書く文化を根付かせる戦略と戦術
 
xUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase ClassxUTP Chapter19 (2). Testcase Class
xUTP Chapter19 (2). Testcase Class
 
TDDBC お題
TDDBC お題TDDBC お題
TDDBC お題
 
フィーチャモデルの描き方
フィーチャモデルの描き方フィーチャモデルの描き方
フィーチャモデルの描き方
 
fluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギングfluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギング
 
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015
事例 アジャイルと自動化 後半(ヤフオク!アプリでの自動テストの事例紹介) at Ques vol.7( #ques7 ) 11/20/2015
 

Semelhante a xUTP Chapter26. Dependency Injection

Unit test in android
Unit test in androidUnit test in android
Unit test in androidTatsuya Maki
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~normalian
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Hiroto Yamakawa
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
20130329 rtm3
20130329 rtm320130329 rtm3
20130329 rtm3openrtm
 
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解GMO GlobalSign Holdings K.K.
 
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しようUnityTechnologiesJapan002
 
Android test tutorial
Android test tutorialAndroid test tutorial
Android test tutorialKazuaki Ueda
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewMitsuru Ogawa
 
C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?Shinichi Hirauchi
 
テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編Hisakuni Fujimoto
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...Yoshifumi Kawai
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaYuta Kawadai
 

Semelhante a xUTP Chapter26. Dependency Injection (20)

CruiseControl.NET設置
CruiseControl.NET設置CruiseControl.NET設置
CruiseControl.NET設置
 
About Jobs
About JobsAbout Jobs
About Jobs
 
Unit test in android
Unit test in androidUnit test in android
Unit test in android
 
Junit4
Junit4Junit4
Junit4
 
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
Spock's world
Spock's worldSpock's world
Spock's world
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能Apache Wicketのユニットテスト機能
Apache Wicketのユニットテスト機能
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
20130329 rtm3
20130329 rtm320130329 rtm3
20130329 rtm3
 
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解
【Photon勉強会】FFGMでも採用!1時間でわかるPlugin開発とEnterprise Cloudの詳解
 
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
【Unite Tokyo 2019】Unity Test Runnerを活用して内部品質を向上しよう
 
wankuma #28
wankuma #28wankuma #28
wankuma #28
 
Android test tutorial
Android test tutorialAndroid test tutorial
Android test tutorial
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overview
 
C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?C# から java へのプログラム移植で体験したtddの効果は?
C# から java へのプログラム移植で体験したtddの効果は?
 
テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編テスティングフレームワークに入門してみた - Swift編
テスティングフレームワークに入門してみた - Swift編
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
 
TDD勉強会キックオフ for Java
TDD勉強会キックオフ for JavaTDD勉強会キックオフ for Java
TDD勉強会キックオフ for Java
 

Mais de Takuto Wada

OSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてTakuto Wada
 
unassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in productionunassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in productionTakuto Wada
 
OSS についてあれこれ
OSS についてあれこれOSS についてあれこれ
OSS についてあれこれTakuto Wada
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」Takuto Wada
 
power-assert, mechanism and philosophy
power-assert, mechanism and philosophypower-assert, mechanism and philosophy
power-assert, mechanism and philosophyTakuto Wada
 
アジャイルサムライの次に読む技術書
アジャイルサムライの次に読む技術書アジャイルサムライの次に読む技術書
アジャイルサムライの次に読む技術書Takuto Wada
 
Test Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTakuto Wada
 
テスト用ライブラリ power-assert
テスト用ライブラリ power-assertテスト用ライブラリ power-assert
テスト用ライブラリ power-assertTakuto Wada
 
Reviewing RESTful Web Apps
Reviewing RESTful Web AppsReviewing RESTful Web Apps
Reviewing RESTful Web AppsTakuto Wada
 
power-assert in JavaScript
power-assert in JavaScriptpower-assert in JavaScript
power-assert in JavaScriptTakuto Wada
 
TDD のこころ @ OSH2014
TDD のこころ @ OSH2014TDD のこころ @ OSH2014
TDD のこころ @ OSH2014Takuto Wada
 
テストを書く文化を育てる戦略と戦術
テストを書く文化を育てる戦略と戦術テストを書く文化を育てる戦略と戦術
テストを書く文化を育てる戦略と戦術Takuto Wada
 
私にとってのテスト
私にとってのテスト私にとってのテスト
私にとってのテストTakuto Wada
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)Takuto Wada
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴
SQLアンチパターン - 開発者を待ち受ける25の落とし穴SQLアンチパターン - 開発者を待ち受ける25の落とし穴
SQLアンチパターン - 開発者を待ち受ける25の落とし穴Takuto Wada
 
愛せないコードを書くには人生はあまりにも短い
愛せないコードを書くには人生はあまりにも短い愛せないコードを書くには人生はあまりにも短い
愛せないコードを書くには人生はあまりにも短いTakuto Wada
 
ペアプログラミング ホントのところ
ペアプログラミング ホントのところペアプログラミング ホントのところ
ペアプログラミング ホントのところTakuto Wada
 
RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話Takuto Wada
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 

Mais de Takuto Wada (20)

OSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係についてOSS活動の活発さと評価の関係について
OSS活動の活発さと評価の関係について
 
unassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in productionunassert - encourage reliable programming by writing assertions in production
unassert - encourage reliable programming by writing assertions in production
 
OSS についてあれこれ
OSS についてあれこれOSS についてあれこれ
OSS についてあれこれ
 
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
 
power-assert, mechanism and philosophy
power-assert, mechanism and philosophypower-assert, mechanism and philosophy
power-assert, mechanism and philosophy
 
アジャイルサムライの次に読む技術書
アジャイルサムライの次に読む技術書アジャイルサムライの次に読む技術書
アジャイルサムライの次に読む技術書
 
Test Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるかTest Yourself - テストを書くと何がどう変わるか
Test Yourself - テストを書くと何がどう変わるか
 
テスト用ライブラリ power-assert
テスト用ライブラリ power-assertテスト用ライブラリ power-assert
テスト用ライブラリ power-assert
 
Reviewing RESTful Web Apps
Reviewing RESTful Web AppsReviewing RESTful Web Apps
Reviewing RESTful Web Apps
 
power-assert in JavaScript
power-assert in JavaScriptpower-assert in JavaScript
power-assert in JavaScript
 
TDD のこころ @ OSH2014
TDD のこころ @ OSH2014TDD のこころ @ OSH2014
TDD のこころ @ OSH2014
 
テストを書く文化を育てる戦略と戦術
テストを書く文化を育てる戦略と戦術テストを書く文化を育てる戦略と戦術
テストを書く文化を育てる戦略と戦術
 
私にとってのテスト
私にとってのテスト私にとってのテスト
私にとってのテスト
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
 
SQLアンチパターン - 開発者を待ち受ける25の落とし穴
SQLアンチパターン - 開発者を待ち受ける25の落とし穴SQLアンチパターン - 開発者を待ち受ける25の落とし穴
SQLアンチパターン - 開発者を待ち受ける25の落とし穴
 
愛せないコードを書くには人生はあまりにも短い
愛せないコードを書くには人生はあまりにも短い愛せないコードを書くには人生はあまりにも短い
愛せないコードを書くには人生はあまりにも短い
 
ペアプログラミング ホントのところ
ペアプログラミング ホントのところペアプログラミング ホントのところ
ペアプログラミング ホントのところ
 
RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話RESTful Web アプリの設計レビューの話
RESTful Web アプリの設計レビューの話
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
DevLOVE DDDBC
DevLOVE DDDBCDevLOVE DDDBC
DevLOVE DDDBC
 

Último

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NTT DATA Technology & Innovation
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 

Último (8)

自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 

xUTP Chapter26. Dependency Injection

  • 1. Chapter 26. Design for Testability Patterns
  • 3. Dependency Injection ● SUT をどう設計すれば、ランタイムに依存オブジェ クトを差し替えられるだろうか? ● クライアントが SUT に対して依存オブジェクトを提供す れば良い ● テストする際には、 SUT を依存から独立してテストでき るのが望ましいが、依存クラス名などがハードコードさ れていると難しい ● Dependency Injection は、 SUT に対する依存オブ ジェクトをテスト時に差し替えるのに使える
  • 4. How It Works ● クライアントコードやシステムの設定部(ファイル/ コード)で、 SUT が実行時に依存するオブジェクトを 渡せるようにする ● この設計のポイントは、 依存が “front door” から 渡せるようになっているところ ● つまり、「依存を渡す」ということも SUT の API の一部 になる ● 依存の渡し方は、メソッドの引数、コンストラクタ、 setter などがある。
  • 5. When to Use It ● まずは、テスト時に DOC を Test Double に差し替 えるときに使う ● Static binding は依存クラス名を SUT に直接書いてし まうことで、採れる手段を大幅に狭めてしまう ● Dynamic binding は依存クラスの解決を実行時まで遅 延することで、柔軟さを得ることができる ● Dependency Injection(DI) はコードをスクラッチ から設計する際には良い手段となる ● 特に TDD で設計している場合には、 DOC を Test Double で差し替えたくなるので、自然と DI が必要にな る
  • 6. Implementation Notes(1) ● 二つの解決すべき問題がある ● Test Double をどんな DOC の場合にも使えるように する必要がある。これは静的型付け言語の場合には、 Test Double をいかにも DOC のように(型を矛盾させ ること無く)渡せなければならないことを意味する ● SUT に Test Double を渡す手段を提供しなければな らない
  • 7. Implementation Notes(2) ● 型の互換性 ● (特に静的型付け言語で) DI を実現するには、 DOC と Test Double が Type Compatible でなければならな い ● 静的型付け言語では、 DOC と Test Double が共通の interface を実装していること ● 動的型付け言語では、 DOC と Test Double が同じ signature (メソッド名など) を持っていること ● 既存のコードに対して DI パターンを導入するには、まず DOC に対して「インターフェイスの抽出」を行い、その抽 出された interface に対して Test Double を書けば良 い
  • 8. Implementation Notes(3) ● Test Double の渡し方 ● さまざまなやり方があるが、名前/型のハードコードを止 め、実行時まで解決を遅らせるという基本は変わらない – Parameter Injection ● 使いたいメソッドの引数として DOC も渡す – Constructor Injection ● SUT 構築時に DOC を渡す – Setter Injection ● どこかのタイミングで setter 経由で DOC を SUT に渡す ● IoC フレームワーク (DI コンテナ) を使うと、 DI の仕組 みの実装自体も作らずに済み、つまり SUT や DOC は DI の実装に対して非依存になり、使いまわしが効くよう になる
  • 9. Motivating Example // リファクタリング前のコード public void testDisplayCurrentTime_AtMidnight() { //fixture setup TimeDisplay sut = new TimeDisplay(); //exercise SUT String result = sut.getCurrentTimeAsHtmlFragment(); //verify direct output String expectedTimeString =     "<span class="tinyBoldText">Midnight</span>"; assertEquals( expectedTimeString, result); } public String getCurrentTimeAsHtmlFragment() { Calendar currentTime; try { currentTime = new DefaultTimeProvider().getTime(); } catch (Exception e) { return e.getMessage(); } // etc. }
  • 10. Parameter Injection // テストコード public void testDisplayCurrentTime_AtMidnight_PI() { //Fixture setup //Test Double instantiation TimeProvider tpStub = new MidnightTimeProvider(); //Instantiate SUT TimeDisplay sut = new TimeDisplay(); //Exercise SUT using Test Double String result = sut.getCurrentTimeAsHtmlFragment(tpStub);     //Verify outcome String expectedTimeString = "<span class="tinyBoldText">Midnight</span>"; assertEquals("Midnight", expectedTimeString, result); } //プロダクトコード public String getCurrentTimeAsHtmlFragment(TimeProvider timeProviderArg) { Calendar currentTime; try { currentTime = timeProviderArg.getTime(); } catch (Exception e) { return e.getMessage(); } // etc. }
  • 11. Constructor Injection // テストコード public void testDisplayCurrentTime_AtMidnight_CI() throws Exception { //Fixture setup //Test Double instantiation TimeProvider tpStub = new MidnightTimeProvider(); //Instantiate SUT injecting Test Double TimeDisplay sut = new TimeDisplay(tpStub); //Exercise SUT String expectedTimeString =     "<span class="tinyBoldText">12:01 AM</span>"; //Verify outcome assertEquals("12:01 AM", expectedTimeString, sut.getCurrentTimeAsHtmlFragment()); } //プロダクトコード public class TimeDisplay { private TimeProvider timeProvider; public TimeDisplay() { //backwards compatible constructor timeProvider = new DefaultTimeProvider(); } public TimeDisplay(TimeProvider timeProvider) { //new constructor this.timeProvider = timeProvider; } ... }
  • 12. Setter Injection(1) // テストコード public void testDisplayCurrentTime_AtMidnight_SI() throws Exception { //Fixture setup //Test Double instantiation TimeProvider tpStub = new MidnightTimeProvider(); //Instantiate SUT TimeDisplay sut = new TimeDisplay(); //Test Double installation     sut.setTimeProvider(tpStub); //Exercise SUT String result = sut.getCurrentTimeAsHtmlFragment(); //Verify outcome String expectedTimeString = "<span class="tinyBoldText">Midnight</span>"; assertEquals("Midnight", expectedTimeString, result); }
  • 13. Setter Injection(2) // プロダクトコード public class TimeDisplay { private TimeProvider timeProvider; public TimeDisplay() { timeProvider = new DefaultTimeProvider(); } public void setTimeProvider(TimeProvider provider) { this.timeProvider = provider; } public String    getCurrentTimeAsHtmlFragment() throws TimeProviderEx { Calendar currentTime; try { currentTime = getTimeProvider().getTime(); } catch (Exception e) { return e.getMessage(); } // etc. } ... }