Есть ли способ обернуть любой вызов функции в блоке try / catch? - PullRequest
4 голосов
/ 08 октября 2010

Я пишу кучу интеграционных тестов для проекта. Я хочу вызывать каждый отдельный метод точки интеграции, заключенный в блок try / catch, чтобы в случае сбоя я мог отображать какую-то обратную связь, а не просто вылетать из приложения. Я также хочу иметь возможность рассчитать, сколько времени занимают вызовы, и проверять возвращаемые значения при необходимости. Итак, у меня есть класс IntegrationResult с некоторым базовым описанием, свойствами результата и прошедшего времени:

class IntegrationResult
{
  private StopWatch _watch;

  public string Description {get;set;}

  public string ResultMessage {get;set;}

  public bool TestPassed {get;set;}

  public string TimeElapsed {get { return _watch == null ? "0" : _watch.Elapsed.TotalMilliseconds.ToString(); } }

  public void Start()
  {
    _watch = StopWatch.StartNew();
  }  

  public void Stop()
  {
    _watch.Stop();
  }
}

Код, который я продолжаю писать, выглядит следующим образом:

IntegrationResult result = new IntegrationResult();
result.Description = "T-SQL returns expected results";

    try
    {
      result.Start();
      SomeIntegrationPoint("potential arguments"); //This is the line being tested
      result.Stop();

      //do some check that correct data is present

      result.TestPassed = true;
      result.ResultMessage = "Pulled 10 correct rows";
    }
    catch(Exception e)
    {

      result.TestPassed = false;
      result.ResultMessage = String.Format("Error: {0}", e.Message);
    }

Мне бы очень хотелось иметь возможность просто передать метод SomeIntegrationPoint в качестве аргумента и делегата или что-то еще, чтобы проверить результаты, но я не могу понять, возможно ли это. Существуют ли какие-либо платформы для обработки такого типа тестирования, или у вас есть какие-либо предложения о том, как можно упростить код для лучшего повторного использования? Я устал набирать этот блок;)

Ответы [ 2 ]

6 голосов
/ 08 октября 2010

(я предполагаю, что это C #, как отмечено ... хотя синтаксис не был в вопросе.)

Вы можете сделать это. Просто измените ваш класс результатов, чтобы включить:

class IntegrationResult
{
      string Description { get; set; }
      string SuccessResultMessage { get; set; }
      string FailResultMessage { get; set; }

      public IntegrationResult(string desc, string success, string fail)
      {
          this.Description = desc;
          this.SuccessResultMessage = success;
          this.FailResultMessage = fail;
      }

      public bool ExecuteTest(Func<IntegrationResult, bool> test)
      {
          bool success = true;
          try
          {
              this.Start();
              success = test(this);
              this.Stop();
              this.ResultMessage = success ? 
                                      this.SuccessResultMessage : 
                                      this.FailResultMessage;
              this.TestPassed = true;
          }
          catch(Exception e)
          {
               this.TestPassed = false;
               this.ResultMessage = String.Format("Error: {0}", e.Message);
               success = false;
          }
          return success;
      }
       ...

Затем вы можете изменить код для своих тестов на:

private void myDoTestMethod(string argumentOne, string argumentTwo)
{
    IntegrationResult result = new IntegrationResult(
                                   "T-SQL returns expected results", 
                                   "Pulled 10 correct rows",
                                   "Wrong number of rows received");
    result.Execute( r=>
    {
         integrationPoint.call(argumentOne, argumentTwo);
         //do some check that correct data is present (return false if not)
         return true;
    });
 }

Это может быть легко расширено, чтобы включить ваши сроки.

0 голосов
/ 08 октября 2010

Вы смотрели в AOP ? PostSharp выглядит как хорошее место для начала. Существует также пример по аспектам обработки исключений.

...