3

こんにちは私はユニットテストを作成している間AutofacでMoqを使用しています。コンストラクターパラメーターに依存するタイプのSUT複数インスタンスがあるシナリオがあります。これらのインスタンスをMoqしたいと思います。私はインターフェースISpanRecordを持っています:

interface ISpanRecord 
{
RecordType RecordType { get; }
string RecordId { get; set; }
string RecordText { get; set; }
ISpanRecord ParentRecord { get; set; }
List<ISpanRecord> Children { get; }
}

RecordType(列挙型)に基づいて新しいISpanRecordを提供する別のインターフェイスIRecordTypeFactoryがあります

interface IRecordTypeFactory
{
ISpanRecord GetNewSpanRecord(RecordType recordType);
}

上記のインターフェースは、SUTSpanParserクラスによって使用されます

internal class SpanParser : ISpanParser
{
// Private Vars
    private ISpanRecord _spanFile;
    private readonly IRecordTypeFactory _factory;
    private readonly ISpanFileReader _fileReader;

//Constructor
public SpanParser(ISpanFileReader fileReader)
    {
        _fileReader = fileReader;
        _spanFile = Container.Resolve<ISpanRecord>(TypedParameter.From(RecordType.CmeSpanFile),
                                                                TypedParameter.From((List<SpanRecordAttribute>)null));
        _factory = Container.Resolve<IRecordTypeFactory>(TypedParameter.From(_fileReader.PublisherConfiguration));
    }

// Method under test
public SpanRiskDataSetEntity ParseFile()
    {
        string currRecord = string.Empty;
        try
        {
            var treeLookUp = Container.Resolve<ITreeLookUp>(TypedParameter.From(_spanFile),
                                                            TypedParameter.From(_fileReader.PublisherConfiguration));

            IList<string> filterLines = _fileReader.SpanFileLines;

            ISpanRecord currentRecord;
            ISpanRecord previousRecord = _spanFile;
            List<string> spanRecords;

            foreach (var newRecord in filterLines)
            {
                currRecord = newRecord;

                //check if we got multiple type of records in a single line.

                spanRecords = _fileReader.PublisherConfiguration.GetMultipleRecordsText(newRecord);
                if (spanRecords == null)
                    continue;

                foreach (var recordText in spanRecords)
                {
                    RecordType recordType = _fileReader.PublisherConfiguration.GetRecordType(recordText);

                    currentRecord = _factory.GetNewSpanRecord(recordType);

                    // some more logic

                    GetPreviousRecord(ref previousRecord, currentRecord);
                }
            }
            // private method
            return GetSpanRiskDataSet();
        }

        catch (OperationCanceledException operationCanceledException)
        {
            // log
            throw;
        } 
    }

上記のクラスでは、テスト中に、RecordType に基づいてISpanRecordの複数のオブジェクトを取得したいと思います。何かのようなもの:

mockFactory.Setup(fc=> fc.GetNewSpanRecord(It.IsAny<RecordType>).Returns(// an ISpanRecord object on the basis of Recordtype)

上記の設定はループで検証されるので、複数のケースを設定したいと思います。解決策を教えてください。または、解決策を教えてください。

よろしく

4

2 に答える 2

3

ReturnsFunc<RecordType, ISpanRecord>複数のオーバーロードがあり、引数として取るものを探しています。それを並べ替えたら、カスタムの return-logic を構築できます。

mockFactory
    .Setup(fc => fc.GetNewSpanRecord(It.IsAny<RecordType>)
    .Returns((RecordType rt) =>
    {
         if (rt.Property == "value") return new DummySpanRecord();
         else if (rt.Property2 == "other value") return new FakeSpanRecord();
         else return new DefaultSpanRecord();
    }); 

abstract factoryの代わりにservice locatorを使用している理由はありますか? コンテナーが SUT に組み込まれていない場合、おそらくテストはより簡単になります (たとえば、コンテナー自体と依存関係の登録プロセスを追跡する必要はありません)。

于 2013-01-14T16:25:33.990 に答える
2

セットアップでは、使用しないでくださいIt.IsAny<RecordType>- 特定の値を使用してください:

mockFactory.Setup(fc=> fc.GetNewSpanRecord(RecordType.Type1)).Returns(// an ISpanRecord object on the basis of Recordtype.Type1)
mockFactory.Setup(fc=> fc.GetNewSpanRecord(RecordType.Type2)).Returns(// an ISpanRecord object on the basis of Recordtype.Type2)

編集:これRecordTypeは、列挙型(または他の値の型)である単純なケースを想定しています。参照型の場合は、jimmy のようなより複雑な手法を使用する必要があります。

于 2013-01-14T16:26:23.273 に答える