1

moqを使用してサードパーティライブラリにメソッドをモックしようとしています。問題は、私がモックしているメソッドがこのフレームワークの内部にあるオブジェクトを返すため、これをインスタンス化できないことです。

以下の例では、ChangeCollectionとItemChangeの両方が内部であり、エラーが発生します:'内部コンストラクターにアクセスできません'ChangeCollection'ここで'

私はこれに対する良い解決策を見つけるのに問題があります、誰かが何かアイデアを持っていますか?

[TestMethod]
public void GetItemsForExistingEMails_should_call_GetItems_atleast_once()
{
    ewsMock = new Mock<IEwsIntegration>();
    ewsMock.Setup(e => e.GetItems()).Returns(new ChangeCollection<ItemChange>);
    var emailService = new EmailService(ewsMock.Object);

    var items = emailService.GetItemsForExistingEMails();

    ewsMock.Verify(e => e.GetItems(), Times.AtLeast(1));
    Assert.AreEqual(0, items.Count());
}

public interface IEwsIntegration
{
    ChangeCollection<ItemChange> GetItems();
}
4

2 に答える 2

0

ここにはいくつかの可能なオプションがあります。

1つ目は、セットアップするためにサードパーティのソースにアクセスできる必要がありますInternalsVisibleTo

http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.internalsvisibletoattribute.aspx

これにより、参照しているdllの内部メンバーにアクセスできるようになり、AssemblyInfo.csでは次のようになります。

[assembly: InternalsVisibleTo("Mynamespace.MyProject.Tests, PublicKey=00240...")]

次にIEwsIntegrationサードパーティのアプリケーションからの型を公開しているので、それを変更して独自の型を返すことができます。これにより、サードパーティアプリからの抽象化が向上します。

ここでは、AutoMapperを使用して、サードパーティアプリのリターンタイプと自分のタイプの間のマッピングを管理します。次に、この依存関係をモックアウトして(私は、IAutoMapperWrapperを使用します)、テストで戻り型の具体的な実装を返すようにすることができます。

独自のカスタムコンバーターを使用する場合でも、それが返すものをモックアウトして、独自のタイプのオブジェクトを提供できます。

于 2012-09-14T13:00:45.570 に答える
0

IEnumerable<ChangeItem>私はあなたがあなたのインターフェースに戻ることで逃げることができると思います。ChangeCollectionはの単なる実装のようですIEnumerable<T>

public interface IEwsIntegration
{
    IEnumerable<ItemChange> GetItems();
}

次に、セットアップでリストを返すだけです。

ewsMock.Setup(e => e.GetItems()).Returns(new List<ItemChange>());

アップデート:

具象クラスでのみ定義されたプロパティを使用する必要があるため、アダプタを作成する必要があります。

まず、具象クラスのメンバーとのインターフェースを作成します。

public interface IChangeCollection<T> : IEnumerable<T>
{
    bool MoreChangesAvailable { get; }
    string SyncState { get; }
}

インターフェイスからこのタイプを返すようにしてください。

public interface IEwsIntegration
{
    IChangeCollection<ItemChange> GetItems();
}

IChangeCollection<T>次に、ChangeCollectionのインスタンスへの呼び出しを単純に指示する実装を作成する必要があります。

public class ChangeCollectionAdapter<T> : IChangeCollection<T>
{
    private readonly ChangeCollection _changeCollection;

    public ChangeCollectionAdapter(ChangeCollection changeCollection)
    {
        _changeCollection = changeCollection;
    }

    public bool MoreChangesAvailable 
    { 
        get { return _changeCollection.MoreChangesAvailable; }
    }

    //other members
}
于 2012-09-14T13:22:24.463 に答える