scottm
scottm

Reputation: 28701

Is there a way to generically wrap any function call in a try/catch block?

I am writing a bunch of integration tests for a project. I want to call each individual integration point method wrapped in a try/catch block so that when it fails, I get some sort of feedback to display, rather than just crashing the app. I also want to be able to time how long the calls take, and check return values when needed. So, I have an IntegrationResult class with some basic description, result and time elapsed properties:

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();
  }
}

The code I keep writing looks like this:

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);
    }

I would really like to be able to just pass the SomeIntegrationPoint method in as an argument and a delegate or something to check the results, but I can't figure out if that's even possible. Are there any frameworks to handle this type of testing, or do you have any suggestions on how I might simplify the code for better reuse? I'm tired of typing this block ;)

Upvotes: 4

Views: 1395

Answers (2)

Reed Copsey
Reed Copsey

Reputation: 564383

(I'm assuming this is C#, as tagged... though the syntax was not in the question.)

You can do this. Just change your result class to include:

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;
      }
       ...

You could then change your code for your tests to:

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;
    });
 }

This can easily be extended to include your timings as well.

Upvotes: 6

m0sa
m0sa

Reputation: 10940

Have you looked into AOP? PostSharp looks like a nice place to start. There is also an example on exception handling aspects.

Upvotes: 0

Related Questions