В С#, как я могу полностью отключить определенные вызовы методов из кодовой базы?
Я пытаюсь избавиться от всех вызовов метода DateTime.Now
и заменить их собственным методом GetNow()
, который иногда может возвращать фиксированную дату для целей тестирования.
Как я могу гарантировать, что никто не добавит вызов DateTime.Now
в будущем? Могу ли я использовать NDepend или StyleCop для проверки этого на моем сервере непрерывной интеграции?
Ответы
Ответ 1
С NDepend очень легко написать это правило:
// <Name>Forbid DateTime.Now, use xxx.GetNow() instead</Name>
WARN IF Count > 0 IN
SELECT METHODS WHERE
IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
Примечание:
- Префикс WARN IF Count > 0 IN, который преобразует запрос CQL в правило
- Способ ссылки на свойство через строку System.DateTime.get_Now()
- Префикс OPTIONAL, который означает "Не испускать ошибку компиляции, если свойство get_Now не найдено". Это имеет смысл, поскольку, если ваш код больше не используется get_Now(), он больше не ссылается на анализ NDepend.
Кроме того, для генерации исходного запроса...
SELECT METHODS WHERE
IsDirectlyUsing "OPTIONAL:System.DateTime.get_Now()"
... просто щелкните правой кнопкой мыши DateTime.get_Now() и выберите "Выбрать методы...", которые непосредственно используют меня
![enter image description here]()
Ответ 2
Во-первых, DateTime.Now
является свойством .
Это означает, что вам не нужно помещать скобки после вызова.
Во-вторых, если в целях тестирования вы имеете в виду инфраструктуру типа NUnit, вы можете проверить Microsoft Moles, который позволяет вам замените любой вызов статического метода с помощью собственной пользовательской реализации при тестировании. Черт, это круто:
[Test]
[ExpectedException (typeof (Y2KBugException))]
public void TestY2KBug ()
{
MDateTime.NowGet = () => new DateTime (2001, 1, 1);
Bomb.DetonateIfY2K ();
}
public static class Bomb {
public static void DetonateIfY2K ()
{
if (DateTime.Now == new DateTime (2001, 1, 1))
throw new Y2KBugException (); // take cover!
}
}
Ответ 3
Нет никакого реального способа принудительного применения чего-либо подобного.
Ближе всего вы собираетесь создать пользовательское правило FxCop или настраиваемое правило анализа кода Visual Studio для ошибки/предупреждения при вызовах DateTime.Now.
Ответ 4
Вы можете использовать Moles в своих тестах, чтобы предоставить свой собственный DateTime.Now, когда это необходимо, без необходимости изменять какой-либо существующий код, который называет это.
Другим вариантом может быть изменение сборки после компиляции для вызова чего-то другого. (Возможно, используйте Mono.Cecil для перезаписи IL и добавьте команду для пост-сборки в VS для ее запуска.)
Возможно, вы можете захватить источник Mono и создать собственный mscorlib с удаленной функцией.
Ответ 5
Один из подходов может заключаться в том, чтобы добавить привязку pre-commit к исходному репозиторию управления версиями для поиска DateTime.Now
и прервать регистрацию, если вы найдете строку-нарушитель. Это не безупречно, и это может раздражать ваших коллег, но это должно помочь сохранить его из кодовой базы.
Ответ 6
Я не думаю, что это возможно. То, что вы на самом деле пытаетесь сделать, это переопределить функциональность структуры DateTime.
Единственный способ, о котором я могу думать, это просто пойти с пользовательским классом, который обернет общую функциональность DateTime и предложит различные функции по запросу...