tags:

views:

116

answers:

4

I am new to unit testing, and would like to know how you would go about unit testing a procedure (in this case a procedure a function that "does something" rather than "return something".

I know that the general idea of testing a function that returns an answer is something like

assert(yourfunction(sample, inputs) == expected_answer);

but am wondering how this would work if something does not return or merely returns a status code.

+2  A: 

You need to be able to test what it does. For example, does your procedure add something to a collection? Set a property? Create a file?

Whatever it is, presumably that change is visible somehow. You just need to work out how to check that effect. Of course, that can be easier said than done sometimes, which is why a functional approach is easier to test when it's suitable :) In particular, effects which modify external resources (the file system, databases etc) and effects which depend on external resources (ditto) are harder to test than those which only change things in a fairly "local" way.

Jon Skeet
+1  A: 

In some cases, what a procedure does is call methods on other dependencies. In such cases, if you're using a dependency injection approach, you can pass in mocks of those dependencies, and use assertions or expectations to make sure that the correct methods are called on the dependencies, with the correct parameters.

JacobM
+1  A: 

For procedures, the "do something" usually involves API calls or other object manipulations.

For example, a procedure may write a row to a file. It uses File I/O API calls (or a File IO object) to do this "write a row".

What you want to do is create "mock" object to stand in for the File. The Mock object has just enough functionality to collect the test results and make them visible to an assertion. Don't overwrite your mock objects, it's a rat-hole of lost time.

In Python, we do things like this.

class MockFile( object ):
    def __init__( self, aFileName, aMode ):
        self.name= aFileName
        self.mode= aMode
        self.buffer= None
    def write( self, aRow ):
        self.buffer= str(aRow)

Now we can provide this mock file to our procedure instead of a real file. Ans we can make assertions about what happened.

class TestSomeProcedure( unittest.TestCase ):
    def testWrite( self ):
        mockFile= MockFile( "name", "w" )
        theProcedureImTesting( args, args, args, mockFile )
        self.assertEquals( "The Row It Was Supposed to Write\n", mockFile.buffer )
S.Lott
A: 

There are many different cases:

Case 1:

    public class A
    {
      public void Foo()
      {
        Init();
      }

      protected virtual void Init()
      {
        Do something;
      }
    }

    [TestFixture]
    public class ATests
    {
      [Test]

      public void Foo_test()
      {
         A aStub = new A_Stub();
         aStub.Foo();
         Assert.IsTrue(aStub.wasInit);
      }

       public class A_Stub : A
       {
          public bool wasInit;

          protected override void Init()
          {
            wasInit = true;
          }
       }
  }

Case 2: When your method depends on another object instead executing a member that belong to the same class. In this case I would recommend to use a Mock framework. I personaly using Rhino.Mocks. You can follow this link to see Rhino.Mocks examples.

Vadim