2009-04-16 12 views
1

私はシングルトンクラスを持っており、そのコードを単体テストできません。ユニットがobj-cでシングルトンをテストする方法は?

私のようなテストを持っている:

Db *db = [[Db alloc] initWithName:@"sample.db"]; 

[db createDb]; 

STAssertEquals([db existDb],YES,@"The db is not created!"); 

しかし、唯一の最初の仕事。秒が実行されるとき、私は常にinitWithNameメソッドから "null"を取得します。シングルトンサポートコードを削除すると、すべて正常に動作します。

私はテストをハックすることができますが(私は今はどういうことか分かりませんが)、これに対処する "poper"の方法が存在するのだろうかと思います。

シングルトンは次の場所にあります。http://code.google.com/p/chibiorm/source/browse/trunk/src/Db.m

+0

テストの外でシングルトンをどのように使用しますか? シングルトンで[[Db alloc] init]を実行するのではなく、代わりに単一インスタンスを返すクラスメソッドを呼び出すべきであると私には思われます。 – pgb

+0

それを使用するコードでは、はい...しかし、内部の動作をどのようにテストしますか? – mamcx

答えて

3

シングルトンは、ユニットテストするのは難しいですし、時には貧弱な設計の結果です。

私がお勧めするのは、まずシングルトンが本当に必要かどうかということです。

0

おそらくFactory patternを使用して、1つのインスタンス(事実上シングルトン)を渡すファクトリを作成することができます。実装はシングルトンではなく、あなたのハートの内容を単体テストできます。

唯一の欠点は、工場出荷時に独自のインスタンスを作成しないと、言語によって保護されていないことです。 C++では、コンストラクタをプライベートにし、工場と単体テストの友達を作ることでこれを克服できます。 Objective-Cにも同様の機能があるかどうかはわかりません。

+0

サンプル実装について知っていますか?私が知っている工場コードは他のもののために使われています... – mamcx

0

私は、2番目のallocでnilを返すべきではないと考えていますが、例外が発生します。シングルトンを使用したい場合は、2つを作成しないでください:)。あなたは私が複数のインスタンスがあることは決してないことを強制するわけではない見ることができるように

@implementation MySingleton 

static id _instance = nil; 

+ instance 
{ 
    if (_instance == nil) { 
     // alloc/init 
     _instance = [[self alloc] init]; 
     … 
    } 
    return _instance; 
} 
… 
@end 

:私はシングルトンを作成することにした場合

しかし、私のクラスは次のようになります。代わりに、インスタンスメソッドを使用してインスタンスを取得するためにこの規約を使用しています。

+1

確かにそれは[[self alloc] init]でなければなりません、そうですか? – Chuck

+0

できます。省略記号が示すように、欠けているものがあります。私は 'initWithName:'のようなパラメータでinit関数を使うことが多いので意図的に省略しました。 今、それを考えてみると、あなたが正しいと思われ、インスタンスが正しく初期化されていることを示すためにそこに立つべきです。 –

0

ここでは、私が答えとして書いたと思われる人が書かれています。これは、必要に応じてシングルトンメソッドからdiffernetインスタンスを提供するための使用カテゴリです。すべての彼らの意見pontificatingをしている者上記

http://twobitlabs.com/2011/02/mocking-singletons-with-ocmock/

他の男「シングルトンが悪いm'kayある」無視されるべきです。私が目的のCに切り替えたときの最初のことは、私が目的のCがJavaではないことを認識したために使用したことのないiOCライブラリを作成することだったので、javaドグマについてブレットする人は無視してください。目標c。

関連する問題