2

私は自分の会社のPrismテンプレートに取り組んでいます。設計時のデータをできるだけ簡単にしたいと思っています。

そのために、ViewModelから継承するDesignクラスを作成しています。DesignViewModelは、私のViewModelのコンストラクターを呼び出します。

私のViewModelコンストラクターは、プリズムメソッドやのようなプロパティを呼び出すことがありますIRegionManager.Regions。NSubstituteを使用するそのインターフェース用のスタブを作成することを考えています。このような:

public class DesginRegionManager : IRegionManager
{
    public IRegionManager CreateRegionManager(){return this;}

    private readonly IRegionCollection regions;
    public DesginRegionManager()
    {
        regions = Substitute.For<IRegionCollection>();   <--------
    }                                                            |
                                                                 |
    public IRegionCollection Regions {get { return regions; }}   |
}                                                                |
                                                                 |
// Using NSubstitute here ----------------------------------------

私はのために同様のことをすることを計画していますIUnityContainer

私はこれまで、単体テスト以外でモックフレームワークを使用したことはありません。このように使うのは悪い考えですか?

本番コードでは呼び出されませんが、実際のアプリケーションではNSubstituteへの依存関係が追加されます。

これには欠点がありますか?

4

1 に答える 1

3

続行する前に、私は以前にcaliburnで作業したことがありますが、Prismの経験はほとんどないので、同様に機能すると想定します。しかし、私はnsubstituteについて少し経験があります。

設計目的で代替品を使用するのは悪い考えですか?

私の短い答えはノーです。

完全に理想的ではありませんが、設計部門(またはコーディングを継続している間UI要素の責任者)がいる場合は、インターフェイスを改善できるため、UIによって実行されるコードを設計プロセスから分離することをお勧めします。リアルタイムで実行されるコードにバグがある場合でも。

代替と言うときは、ビジュアルスタジオまたはブレンドによって設計時に作成される実際の(サンプルデータのような)インスタンスについて話します。(最後にサンプルを提供します)。

これらの要素をあざけるのは悪い考えですか?

プロジェクトの実行にとってそれほど重要ではない依存関係をプロジェクトに追加することになるかもしれませんが、そうではないかもしれません。

それの良い面は次のとおりです。

モックされた定義は、維持するコードが少なくなることを意味しますが、これらの偽のインスタンスでデータをシミュレートすることはできません(または、各モックのサンプルデータを返し始めない限りシミュレートできません)。

これのマイナス面:

まず、モックフレームワークに応じて、呼び出しやその他のものを傍受する特定の動作をシミュレートするために、オンザフライで作成されたプロキシまたは偽物のインスタンスを(設計時に)ロードします。実際のコードほど軽量ではないオブジェクトを大量に作成する場合は、面倒な操作になる可能性があります。

デザイナーに加えて(ブレンドの第一人者が1人いる場合)、地獄の代用(または好みのモックフレームワーク)がどのように機能するかについての知識を収集する必要があります。

私がデザイナーのキャップを持っていて、複製できる特定の定義を持つクラスと、substituteと呼ばれる外部ライブラリで定義されたクラスを見せてくれた場合、他に何も学ぶ必要がないので、最初のオプションを好むと言うかもしれません少しのc#以外。そして、そのようにさえ、私はそのコードに触れようとはしません。

プロジェクトにnsubstituteを追加することの欠点はありますか?

DesignInstanceを正しく使用していて、モックを使用したコードの参照が実際の機能から分離されており、非仮想プロパティ、または複数のパラメーターや封印されたクラスを持つインスタンスを置き換えようとしていない限り(基本的に、nsubstituteの制限代わりに)デザイン属性はコードの特別なモードで実行されるため、問題はありません。

特にNSubstituteは、インスタンスを作成しようとしたり、特定のプロパティにアクセスしようとしたりするときに例外をスローする場合があります。その場合、IDEがクラッシュしたり、ロード中にコントロールがクラッシュしたりする可能性があります。

サンプルはありますか?

あなたはおそらく何を書くべきか知っているでしょう、しかしここにそれは行きます(しかしプリズムではありません)。

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/winfx/expression/blend/2008"
    xmlns:vm="clr-namespace:Project.Namespace.ViewModels.DataSamples"
    d:DataContext="{d:DesignInstance IsDesignTimeCreatable=True, Type={x:Type NationViewModelSampleData}}">

    <StackPanel DataContext="{Binding Leader}">
        <TextBlock Text="{Binding FirstName}" />
        <TextBlock Text="{Binding LastName}" />
    </StackPanel>
</UserControl>

NationViewModelがこのようなインターフェースを実装した場所

namespace Project.Namespace.ViewModels
{
    public interface INationViewModel
    {
        IPerson Leader { get; }
        IEnumerable<IPerson> Citizens { get; }
    }

    public interface IPerson
    {
        string FirstName { get; }
        string LastName { get; }
    }
}

また、サンプルデータは次のとおりです。

namespace Project.Namespace.ViewModels.DataSamples
{
    public class NationViewModelSampleData : Project.Namespace.ViewModels.INationViewModel
    {
        public NationViewModelSampleData()
        {
            // You could have done something like this as well, but for this sample was more code to write.
            // Leader = Substitute.For<IPerson>();
            // Leader.FirstName.Returns("John");
            // Leader.LastName.Returns("Doe");
            // or just...
            Leader = new Person { FirstName = "John", LastName = "Doe" };

            Citizens = new IPerson[]
                       {
                           new Person { FirstName = "Malcolm", LastName = "Little" },
                           Leader
                       };
            // You could have applied the mock to this section as well... again, more code for this scenario than just a simple real instance.
        }

        public IPerson Leader { get; private set; }
        public IEnumerable<IPerson> Citizens { get; private set; } 
    }
}

このサンプルでは、​​Personの想像上の実装が非常に小さく、安全に使用できるため、実際のインスタンスを使用することにしました...しかし、複雑さが増すと予想します。その余裕を減らして、PersonSampleDataを実装するだけです。前に説明したように、インスタンスまたはモックします。

このコメントがお役に立てば幸いです。

乾杯!

于 2012-05-18T06:27:17.233 に答える