如何在程序集中使用InternalsVisibleTo设置对象,以使用Rhino mocks 3.6实现部分模拟



下面,我有一个要测试的对象的代码。它在一个名为Business的程序集中,我在AssemblyInfo.cs中添加了属性,以使内部对位于另一个程序集中的测试和rhino mock可见。在测试GenerateReport方法时,当ValidateWorkingDirectory是"内部"时,我不能伪造对它的调用(System.ApplicationException:在任何方法调用之前都必须设置WorkingDirectory。)。如果我将ValidateWorking Directory设为公共,问题就会消失。我认为InternalsVisibleTo会解决这个问题。

public class MyClass : IMyClass
{
    private readonly IMyClassDataProvider _myClassDataProvider;
    public virtual string WorkingDirectory { get; set; }
    public MyClass(IMyClassDataProvider myClassDataProvider)
    {
        _myClassDataProvider = myClassDataProvider;
    }
    internal virtual void ValidateWorkingDirectory()
    {
        if (string.IsNullOrEmpty(WorkingDirectory))
        {
            throw new ApplicationException("Must set Working Directory before any method calls.");
        }
    }
    public virtual void GenerateReport(vars)
    {
        ValidateWorkingDirectory();
        InsertData(_myClassDataProvider.GetData(vars), "ReportName");
    }
    internal virtual void InsertData(DataSet analysis, string fileName)
    {
        DoSomeStuff();
    }
    private static void DoSomeStuff()
    {
        //Whatevs
    }
}
//In AssmeblyInfo.cs
[assembly: InternalsVisibleTo("UnitTests.Business")]
[assembly: InternalsVisibleTo("Rhino.Mocks")]

[TestFixture]
public class MyClassTests : TestFixtureBase
{
    private MockRepository _mocks;
    private IMyClassDataProvider  _myClassDataProvider;
    private MyClass _myClass;
    private var _vars;
    [SetUp]
    protected void Init()
    {
        _mocks = new MockRepository();
        _myClassDataProvider = _mocks.StrictMock<IMyClassDataProvider >();
        _myClass = _mocks.PartialMock<MyClass>(_myClassDataProvider);
        _vars = "who cares";
    }
    [Test]
    [ExpectedException(typeof(ApplicationException), ExpectedMessage = "Must set Working Directory before any method calls.")]
    public virtual void ShouldThrowAnExceptionIfWorkingDirectoryNotSet()
    {
        Expect.Call(_myClass.WorkingDirectory).Return(Random.Get<bool>() ? null : string.Empty);
        _mocks.ReplayAll();
        _myClass.ValidateWorkingDirectory();
        _mocks.VerifyAll();
    }
    [Test]
    public virtual void ShouldGenerateReport()
    {
        DataSet dataSetToReturn = new DataSet();
        using (_mocks.Ordered())
        {
            Expect.Call(() => _myClass.ValidateWorkingDirectory());
            Expect.Call(_myClassDataProvider.GetData(vars)).Return(dataSetToReturn);
            _myClass.InsertData(dataSetToReturn, "ReportName");
        }
        _mocks.ReplayAll();
        _myClass.GenerateReport(vars);
        _mocks.VerifyAll();
    }
}

您需要将内部成员暴露给代理程序集,而不是Rhino的程序集本身:

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]

当一个类被模拟时,一个新的类在运行时生成,它是从模拟的类派生的此生成的类驻留在一个单独的"临时"程序集中,该程序集称为"DynamicProxyGenAssembly2"。因此,需要在目标程序集上设置InternalsVisibleTo属性,以允许从临时程序集访问其内部成员。

这恰好是一个常见的误解,有关如何使用Rhino可见内部结构的详细信息,请查看此文档页面。

相关内容

  • 没有找到相关文章

最新更新