Я работаю над большим проектом, в котором базовый класс имеет тысячи классов, полученных из него (на них работают несколько разработчиков). Ожидается, что каждый класс переопределит набор методов. Сначала я создал эти тысячи файлов классов с шаблоном кода, который соответствует приемлемому шаблону. Теперь я пишу модульные тесты, чтобы разработчики не отклонялись от этого шаблона. Вот пример сгенерированный класс:Проверка кода против шаблонов шаблонов с использованием отражения
// Base class.
public abstract partial class BaseClass
{
protected abstract bool OnTest();
}
// Derived class. DO NOT CHANGE THE CLASS NAME!
public sealed partial class DerivedClass_00000001: BaseClass
{
/// <summary>
/// Do not modify the code template in any way.
/// Write code only in the try and finally blocks in this method.
/// </summary>
protected override void OnTest()
{
bool result = false;
ComObject com = null;
// Declare ALL value and reference type variables here. NOWHERE ELSE!
// Variables that would otherwise be narrowly scoped should also be declared here.
// Initialize all reference types to [null]. [object o;] does not conform. [object o = null;] conforms.
// Initialize all value types to their default values. [int x;] does not conform. [int x = 0;] conforms.
try
{
com = new ComObject();
// Process COM objects here.
// Do NOT return out of this function yourself!
}
finally
{
// Release all COM objects.
System.Runtime.InteropServices.Marshal.ReleaseComObject(com);
// Set all COM objects to [null].
// The base class will take care of explicit garbage collection.
com = null;
}
return (result);
}
}
В модульных тестов, я был в состоянии проверить следующее с помощью отражения:
- Класс происходит от [BaseClass] и не реализует никаких интерфейсов.
- Название класса соответствует образцу.
- Блокировка не отфильтрована.
- Никаких других блоков блокировки не было добавлено.
- Поля или свойства уровня класса не объявлены.
- Все переменные типа значения метода были инициализированы вручную после объявления.
- Никакие другие методы не были добавлены к производным классам.
выше легко достигается с помощью отражения, но я борюсь с утверждающим следующим списком:
- Улова блок повторно бросает пойманное скорее исключение, чем оборачивать его или бросать некоторые другие исключения.
- Линия
[return (result);]
в конце не была изменена, и никакие другие[return (whatever);]
звонки были добавлены. Не знаю, как этого добиться. - Убедитесь, что все ссылочные типы, реализующие IDisposable, были удалены.
- Убедитесь, что все ссылочные типы типа [System .__ ComObject] были вручную удалены и установлены в [null] в блоке finally.
Я думал о разборе исходного кода, но мне не нравится это решение, если это абсолютно необходимо. Это грязно, и если у меня нет деревьев выражений, почти невозможно гарантировать успех.
Любые советы будут оценены.
Просто подумайте: если методы * need * будут переопределены, почему они являются «виртуальными», а не «абстрактными»? –
Исправлено. Typo, так как я писал пример в редакторе SO. –