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

这里有几个可能的选择。

第一个要求您有权访问第 3 方源进行设置InternalsVisibleTo

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

然后,这允许您访问正在引用的 dll 上的内部成员,并且在 AssemblyInfo.cs 中看起来像这样:

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

其次,由于IEwsIntegration公开了来自 3rd 方应用程序的类型,因此您可以更改它以便返回自己的类型。这将使您从 3rd 方应用程序中获得更好的抽象。

在这里,我将使用 AutoMapper 来管理 3rd 方应用程序的返回类型与我自己的类型之间的映射。然后,您可以模拟此依赖项(我使用 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 回答