質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

4000閲覧

iOSの時間系のテストで、時間を変更する方法

yoneapp

総合スコア85

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

1クリップ

投稿2015/08/15 15:52

編集2015/08/16 08:28

iOSのNSDate系のテストを書いています。時間に応じて結果が変化するメソッドがあるので、テスト中に時間を変更したいと思っています。

以下のライブラリなどを見つけましたが、みなさんは何を使っていますか。
https://github.com/kazu0620/ios-timecop

いつも2〜3個と比較して使うライブラリを決めているので、他の候補も知りたいと思いました。

ご存知のものありましたら、アドバイスを頂けますと幸いです。

ios-timecop は私の環境では動きませんでした。

もしかしたら設計的にもNSDate()に依存するメソッドは良くないし、Swift的にも出来ない?のかもしれませんね。
http://stackoverflow.com/questions/29889246/how-to-mock-nsdate-in-swift

【追記】

以下の様なinExpiryDateNowの帰り値を端末の時間に応じてテストすることを想定しています。

swift

1public func inExpiryDateNow -> Bool { 2 return NSDate() < expiryDate 3} 4public var expiryDate: NSDate { 5 get { 6 ... 7 } 8}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

やり方はいろいろありますが、基本的にはご提示の例のような、内部で使われていてコントロールできないけれど、最終的なアウトプットに影響を与える値(間接入力などといいます)がある場合はテストが困難になりますので、それを外部からコントロールできるようにしなければなりません。
(あくまでテストする必要性があって、実装のコストや複雑性とのバランスによります。ご提示の実装はテストしにくいですが、悪いとは思いません。)

一つは簡単に、NSDate()を使っているところを外部から与えられるインスタンス変数にするなどです。
例えばインスタンス変数currentDateなどを作成時に受け取るようにします。

swift

1public func inExpiryDateNow -> Bool { 2 return currentDate < expiryDate 3}

さらに、アプリケーションのあらゆるところで日付は使われるので、日付を扱う箇所はすべて専用のラッパークラスなどを使って直接NSDateなどをAPIを使わないという方法もあります。

例えば日付関連の操作はすべてDateUtilなどというクラスを使って行うようにする、などです。

swift

1public func inExpiryDateNow -> Bool { 2 return dateUtil.currentDate < expiryDate 3}

そうすると、アプリケーションのあらゆるところでDateUtilへの依存ができてしまって困る、ということにだんだんなってくるので、依存度を下げるためにDIや共通のインターフェースなどを使って入れ替え可能にするなど発展していきます。

まあ、普通はそこまで徹底的にやることはないですが、いずれにしても、内部の状態が実行するたびに変わるというのはテストには向かないので、そういう部分をコントロール可能にしていく、というのが基本になります。

もちろんモックを使ってNSDateそのものをすげ替えるという方法もありますが、(RubyのTimeCopはそういう発想)Swiftはダイナミックな言語ではないので、そういう手段を使うのは却って難しくなることが多いです。

投稿2015/08/20 17:39

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoneapp

2015/08/29 07:58

Swiftはダイナミックな言語ではないので、RubyのTimeCopのようなものは難しいこと。内部で使われている値を、場合によってコントロールしテストするようにするなど理解出来ました。ありがとうございました!
guest

0

テストでしたら直接NSDateの値で時間比較するのではなく、
NSDateを加工して返すラッパー関数を用意すれば良いように思いますが如何でしょうか?
ラッパー関数では固定の時間を返したり、NSDateに+n時間した時間を返せばと思います。

投稿2015/08/16 03:09

buibui80

総合スコア1033

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoneapp

2015/08/16 08:27 編集

ご回答ありがとうございます。追記した様なinExpiryDateNowの返り値をテストしたいのですが、この場合だとラッパー関数で固定の時間を返したり+n時間した時間を返すのはどうすればいいでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問