После обновления до Castle Trunk и NHibernate 2.1.0.4000 Мои интеграционные тесты завершаются сбоем TestDriven.Net
-
11-09-2019 - |
Вопрос
У меня есть старая монорельсовая дорога / ActiveRecord, над которой я тоже кое-что поработал.
Недавно я решил обновить приложение до Castle Trunk & NHibernate 2.1.0.4000 GA, и теперь я нахожу несколько проблем с запуском тестов:
Во-первых, при использовании TestDriven.Net для запуска интеграционных тестов, которые работают с базой данных, происходит сбой TestDriven.Net в целом, или все тесты завершают выполнение, затем TestDriven.Сеть висит.Этого никогда не происходило до обновления.
Когда TestDriven.Сбой сети, вот что записывается в журнал событий:
Блок неисправностей 1467169527, тип 1 Название события:СБОЙ ПРИЛОЖЕНИЯ Ответ:Недоступно Идентификатор кабины:0
Сигнатура проблемы:Р1:ProcessInvocation86.exe Р2:2.22.2468.0 Р3:4a26845c P4:KERNELBASE.dll Р5:6.1.7600.16385 Р6:4a5bdbdf P7:e053534f P8:0000b727 P9:Р10:
Вторая вещь - исключения регистрируются, когда прокси-классы завершают () 'd, как показано ниже - кажется, это происходит после того, как это регистрируется пару раз, то есть когда TestDriven.Сбой сети.
Вот трассировка стека для исключения:
NHibernate.LazyInitializationException:
Initializing[MyApp.Core.Models.TestExecutionPackage#15d9eb96-faf0-4b4b-9c5c-9cd400065430]-Could not initialize proxy - no Session.
at NHibernate.Proxy.AbstractLazyInitializer.Initialize()
at NHibernate.Proxy.AbstractLazyInitializer.GetImplementation()
at NHibernate.ByteCode.Castle.LazyInitializer.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.TestExecutionPackageProxy.Finalize()
Такое же поведение также приведет к сбою MSBuild на нашем сервере CI.
Что действительно странно, так это то, что теоретически исключения, генерируемые в Finalize(), должны проглатываться в соответствии с документами MSDN:
http://msdn.microsoft.com/en-us/library/system.object.finalize (ПРОТИВ 71).aspx
Если Завершить или переопределение Завершить генерирует исключение, среда выполнения игнорирует исключение, завершает это Завершить метод, и продолжает процесс доработки.
Мысли у кого-нибудь есть?
Решение
Так и не до конца разобрался в этой проблеме, но в итоге я реализовал довольно элементарный способ обхода, создав свою собственную реализацию LazyInitializer, где я проверяю наличие метода Finalize при вызове, как показано ниже:
/// <summary>
/// Invoke the actual Property/Method using the Proxy or instantiate the actual
/// object and use it when the Proxy can't handle the method.
/// </summary>
/// <param name="invocation">The <see cref="IInvocation"/> from the generated Castle.DynamicProxy.</param>
public virtual void Intercept(IInvocation invocation)
{
try
{
if (invocation.Method.Name == "Finalize")
{
return;
}
if (_constructed)
{
// let the generic LazyInitializer figure out if this can be handled
// with the proxy or if the real class needs to be initialized
invocation.ReturnValue = base.Invoke(invocation.Method, invocation.Arguments, invocation.Proxy);
// the base LazyInitializer could not handle it so we need to Invoke
// the method/property against the real class
if (invocation.ReturnValue == InvokeImplementation)
{
invocation.ReturnValue = invocation.Method.Invoke(GetImplementation(), invocation.Arguments);
return;
}
else
{
return;
}
}
else
{
// TODO: Find out equivalent to CGLIB's 'method.invokeSuper'.
return;
}
}
catch (TargetInvocationException tie)
{
// Propagate the inner exception so that the proxy throws the same exception as
// the real object would
Exception_InternalPreserveStackTrace.Invoke(tie.InnerException, new Object[] { });
throw tie.InnerException;
}
}
Другие советы
У меня была такая же проблема, когда я перешел на версию NHibernate 2.1.2.Я сменил Castle на LinFu Proxy, и тогда у меня все работало нормально.Надеюсь, это поможет.