Подтвердить что ты не робот

В С#, как я могу полностью отключить определенные вызовы методов из кодовой базы?

Я пытаюсь избавиться от всех вызовов метода DateTime.Now и заменить их собственным методом GetNow(), который иногда может возвращать фиксированную дату для целей тестирования.

Как я могу гарантировать, что никто не добавит вызов DateTime.Now в будущем? Могу ли я использовать NDepend или StyleCop для проверки этого на моем сервере непрерывной интеграции?

4b9b3361

Ответ 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!
    }
}

Ответ 4

Вы можете использовать Moles в своих тестах, чтобы предоставить свой собственный DateTime.Now, когда это необходимо, без необходимости изменять какой-либо существующий код, который называет это.

Другим вариантом может быть изменение сборки после компиляции для вызова чего-то другого. (Возможно, используйте Mono.Cecil для перезаписи IL и добавьте команду для пост-сборки в VS для ее запуска.)

Возможно, вы можете захватить источник Mono и создать собственный mscorlib с удаленной функцией.

Ответ 5

Один из подходов может заключаться в том, чтобы добавить привязку pre-commit к исходному репозиторию управления версиями для поиска DateTime.Now и прервать регистрацию, если вы найдете строку-нарушитель. Это не безупречно, и это может раздражать ваших коллег, но это должно помочь сохранить его из кодовой базы.

Ответ 6

Я не думаю, что это возможно. То, что вы на самом деле пытаетесь сделать, это переопределить функциональность структуры DateTime.

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