Как настроить объект с InternalsVisibleTo в сборке для реализации частичных имитаций с помощью Rhino Mocks 3.6 - PullRequest
2 голосов
/ 02 февраля 2012

Ниже у меня есть код для объекта, который я хотел бы проверить.Он находится в сборке с именем Business, и я добавил атрибуты в AssemblyInfo.cs, чтобы сделать внутреннюю часть видимой для тестов и макетов носорога, которые находятся в другой сборке.При тестировании метода 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();
    }
}

1 Ответ

1 голос
/ 03 февраля 2012

Вам нужно выставить своих внутренних членов на сборку прокси , а не на саму сборку Rhino:

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]

Когда класс подвергается моделированию, во время выполнения генерируется новый класс, который является производным от моделируемого класса. Этот сгенерированный класс находится в отдельной «временной» сборке, которая называется «DynamicProxyGenAssembly2» . Таким образом, атрибут InternalsVisibleTo должен быть установлен в целевой сборке, чтобы разрешить доступ к его внутренним элементам из временной сборки.

Это часто встречающееся недоразумение, для получения подробной информации о том, как использовать внутренние устройства, видимые в Rhino, проверьте эту страницу документации .

...