下面,我有一个我想测试的对象的代码。它位于一个名为Business的程序集中,我在AssemblyInfo.cs中添加了属性,以使测试的内部构件和位于另一个程序集中的rhino mocks可见。在测试GenerateReport方法时,我无法伪造对ValidateWorkingDirectory的调用,因为它是“内部”(System.ApplicationException:必须在任何方法调用之前设置工作目录)。如果我公开ValidateWorkingDirectory,问题就会消失。我认为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();
}
}
答案 0 :(得分:1)
您需要将内部成员公开给代理程序集,而不是Rhino的程序集本身:
[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]
当一个类被模拟时,会在运行时生成一个新类,该类派生自模拟类。 此生成的类驻留在一个单独的“临时”程序集中,该程序集称为“DynamicProxyGenAssembly2”。因此,需要在目标程序集上设置InternalsVisibleTo属性,以允许从临时程序集访问其内部成员。
这恰好是常见的误解,有关如何使用Rhino可见内部的详细信息,请查看this documentation page。