RhinoMocks

I am digging deeper into fakes using RhinoMocks.  I set up a test project that uses a Mock of an InterfaceKit and then sets up some expected return values.  For example:

        [TestInitialize()]
        
public void InterfaceKitTestInitialize()
        {
            
MockRepository mockRepository = new MockRepository();
            interfaceKit = mockRepository.StrictMock<
IInterfaceKit>();
            
Expect.Call(interfaceKit.Address).Return("ValidAddress");
            mockRepository.ReplayAll();
        }

 

And a subsequent test:

        [TestMethod()]
        
public void
 InterfaceKitAddress_ReturnsValidValue()
        {
            
string expected = "ValidAddress"
;
            
string
 actual = interfaceKit.Address;
            
Assert.AreEqual(expected, actual);
        }

 

So far so good – it comes back green.  But then I thought “So what?”  All I am really doing is testing the Mock API.  Unless there is some business logic in the getter, then mocking properties are useless.  I guess you would use a mock over a stub because you can control the number of properties that you need to test – you don’t have to set up a whole  object graph if you just want to test 1 property.

I also noticed that I could use this syntax instead of using Expect.Call:

SetupResult.For(interfaceKit.Address).Return("ValidAddress");

 

 I then tried to venture on to mock a method.  I attempted to add a new line to my initialization method like this:

Expect.Call(interfaceKit.open());
 

However, I am getting some errors:

I then realized that I had a syntax error for parameter-less methods:

Expect.Call(interfaceKit.open).Return(null);

 This works – but I am not testing anything.  So I thought a bit more – why would you even mock a method that does not return a value and does not take a parameter?  Unless there is another dependency that the method needs to run (for example, setting a property of the object before calling the method) and the only way you know if it ran was if you got an exception, there is no point.

Expect.Call(interfaceKit.open).Throw(new PhidgetException(ErrorType.PHIDGET_ERR_CLOSED));

I guess this is what they mean when they say that mocking and unit testing forces you to make a better API.  The Phidget kit does this (open then wait for the event).  I then made a test to check the exception

        [TestMethod()]
        [
ExpectedException(typeof(PhidgetException
))]
        
public void
 InterfaceKitAttachedTest_ThrowsError()
        {
            interfaceKit.open();
            
Assert.Fail("Should never get here");
        }

 and the test passed.  If I wanted to test the value of the ErrorType, I would put it into a try..catch block in the test and inspect the PhidgetException.ErrorType property and remove the ExpectedException attribute.

Advertisements

Autocreate Tests

Dear Microsoft:

When you autocreate a test class, can you include the name of the class in the initialize methods?

        #region Additional test attributes
        [
TestInitialize()]
        
public void MyTestInitialize()
        { 
        }
        
        [
TestCleanup()]
        
public void MyTestCleanup()
        { 
        }

Yuck

        [TestInitialize()]
        public void InterfaceKitTestInitialize()
        {         }
        
        [
TestCleanup
()]         public void InterfaceKitTestCleanup()         {         }

Yum

 

From,

Jamie Dixon

Chaining Tests

I learned something new about tests this morning.  Methods that are called from a test that have an Assert in them will be treated as a test.  For example:

        InterfaceKit interfaceKit = null;
 
        [
TestMethod()]
        
public void InterfaceKitAttachedTest_ReturnsTrue()
        {
            interfaceKit = 
new InterfaceKit();
            interfaceKit.Attach += 
new Events.AttachEventHandler(interfaceKit_Attach);
            interfaceKit.open();
        }
 
        
void interfaceKit_Attach(object sender, Events.AttachEventArgs e)
        {
            
bool expected = true;
            
bool actual = interfaceKit.Attached;
            
Assert.AreEqual(expected, actual);
            interfaceKit.close();
        }

 

Thinking about it, that makes sense – b/c the called method is sharing the stack so the Assert will be called and inspected.

Code Coverage: More Is Less?

I started working on some unit tests for the PhidgetException class.  Following the DRY principles, I re-wrote the constructor logic from this

    internal PhidgetException(int code) : base(string.Concat(new object[] { "PhidgetException ", code, " (", GetErrorDesc(code), ")" }))

    {

        this.desc = "Uninitialized Error";

        this.errType = this.errorCodeToErrorType(code);

        this.errCode = code;

        this.desc = GetErrorDesc(code);

    }

 

    public PhidgetException(string message, ErrorType type) : base("PhidgetException " + type.ToString() + " (" + message + ")")

    {

        this.desc = "Uninitialized Error";

        this.errType = type;

        this.errCode = 0;

        this.desc = message;

    }

 

    public PhidgetException(string message, int code) : base(string.Concat(new object[] { "PhidgetException ", code, " (", message, ")" }))

    {

        this.desc = "Uninitialized Error";

        this.errType = this.errorCodeToErrorType(code);

        this.errCode = code;

        this.desc = message;

    }

 

to this:

        public PhidgetException(string message, ErrorType errorType, int errorCode)
            : base(string.Concat(new object[] { "PhidgetException ", errorCode, " (", GetErrorDesc(errorCode), ")" }))
        {
            if (errorType == ErrorType.PHIDGET_ERR_OK && errorCode != 0)
            {
                this._errorCode = errorCode;
                this._errorType = this.ErrorCodeToErrorType(errorCode);
            } 
            
if (errorType != ErrorType
.PHIDGET_ERR_OK && errorCode == 0)             {                 this._errorCode = ErrorTypeToErrorCode(errorType);                 this._errorType = errorType;
            }

            
if (errorType != ErrorType
.PHIDGET_ERR_OK && errorCode != 0)             {                 int expectedErrorCode = ErrorTypeToErrorCode(errorType);                 if (expectedErrorCode != errorCode)                 {                     throw new ArgumentException("Error Code and Error Type Do Not Match");                 }                 else                  {                     this._errorCode = errorCode;                     this._errorType = errorType;                 }             }            
            
if (message == string
.Empty)                 this._errorDescription = GetErrorDesc(errorCode);             else                 this._errorDescription = message;         }
 
        
public PhidgetException(string message, ErrorType
 errorType)             : this(message, errorType, 0)         {         }
 
        
public PhidgetException(string message, int
 errorCode)             : this(message, ErrorType.PHIDGET_ERR_OK, errorCode)         {         }

 Honestly, the 1st constructor should be marked as private so that you can’t ever get to that ArgumentException, but that is another day’s refactoring.

I then layered some Unit Tests on top of the different constructors to see if my logic worked:

        [TestMethod()]
        public void PhidgetExceptionConstructorTest_Code1_ReturnsPHIDGET_ERR_NOTFOUND()
        {
            PhidgetException phidgetException = new PhidgetException("Test Message", 1);
            ErrorType expected = ErrorType.PHIDGET_ERR_NOTFOUND;
            ErrorType actual = phidgetException.Type;
            Assert.AreEqual(expected, actual);
        }
        [TestMethod()]         [ExpectedException(typeof(ArgumentException))]         public void PhidgetExceptionConstructorTest_PHIDGET_ERR_NOMEMORY_ErrorCode3_ThrowsException()         {             ErrorType errorType = ErrorType.PHIDGET_ERR_NOMEMORY;             PhidgetException phidgetException = new PhidgetException("Test Message", errorType,3);             Assert.Fail("Should Never Get Here");         }

        [
TestMethod
()]         public void PhidgetExceptionConstructorTest_PHIDGET_ERR_NOMEMORY_ErrorCode2_ReturnsErrorCode2AndPhidgetNoMemory()         {             ErrorType errorType = ErrorType.PHIDGET_ERR_NOMEMORY;             int errorCode = 2;             string message = "Test Message";             PhidgetException phidgetException = new PhidgetException(message, errorType, errorCode);             Assert.AreEqual(errorCode, phidgetException.Code);             Assert.AreEqual(errorType, phidgetException.Type);
        }

So far so good. 

I then did a code coverage analysis of my project.  Note that the Code Coverage screens in VS2010 are not the most intuitive, you need to press that cleverly-hidden “Configure” label (why no Button VS team?):

I re-ran the tests and expected some high metrics.

 

47% – WTF?

Drilling down, I saw that I did not check the internal method.  Easy enough to fix, I added

[assemblyInternalsVisibleToAttribute("Com.Tff.Phidget.Tests")]

 to my PhidgetException code file (above the namespace, please), wrote a couple of covering Unit Tests

        [TestMethod()]
        public void GetErrorDescriptionTest_ErrorCode2_ReturnsValidString()
        {
            string notExpected = string.Empty;
            string actual = PhidgetException.GetErrorDesc(2);
            Assert.AreNotEqual(notExpected, actual);
        }
          [
TestMethod
()]         [ExpectedException(typeof(PhidgetException))]         public void GetErrorDescriptionTest_ErrorCodeNeg1_ThrowsException()         {             string notExpected = string.Empty;             string actual = PhidgetException.GetErrorDesc(-1);             Assert.Fail("Should Never Get Here");         }
 

 And now got

 

50%????!!!!  What is going on here?  I have no other methods to cover.  Drilling down, I re-learned the lesson of paying too much attention to Code Coverage.  Check out the code coverage of the 2 lookup methods.

These lookup methods look like this:

 You can see that unless I write 30 covering unit tests for each possible error code and inspect the return value, I will have low code coverage.  A good lesson re-learned.

Importance Of Variable Names

Can anyone see the problem with this bit of code?

    public class InterfaceKitDigitalOutputCollection
    {
        
// Fields
        private IntPtr phid;
 
        
// Methods
        internal InterfaceKitDigitalOutputCollection(InterfaceKit phid)
        {
            
this.phid = phid.phidgetDeviceHandle;
        }

 

I changed the local parameter

        // Methods
        internal InterfaceKitDigitalOutputCollection(InterfaceKit
 interfaceKit)
        {
            
this.phid = interfaceKit.phidgetDeviceHandle;
        }

 

And suddenly the code is more consistent and readable.  A small change to be sure, but I lost 5 minutes assuming that variable names were unique in the class.

Unsafe At Any Speed

What I wrote in Visual Studio 2010:   

    

 public unsafe void waitForAttachment(int milliseconds)
        {
            
if (this.managerPhidget)
            {
                
throw new PhidgetException(PhidgetException.GetErrorDesc(11), 11);
            }
            
int code = Phidget21Imports.CPhidget_waitForAttachment(this.phidgetDeviceHandle, milliseconds);
            
if (code != 0)
            {
                
throw new PhidgetException(code);
            }
            
while (!this.initialized)
            {
                
Thread.Sleep(10);
            }
        }

 

 What Reflector came up with:

public void waitForAttachment(int milliseconds)

{

    if (this.managerPhidget)

    {

        throw new PhidgetException(PhidgetException.GetErrorDesc(11), 11);

    }

    int code = Phidget21Imports.CPhidget_waitForAttachment(this.phidgetDeviceHandle, milliseconds);

    if (code != 0)

    {

        throw new PhidgetException(code);

    }

    while (!this.initialized)

    {

        Thread.Sleep(10);

    }

Note how Reflector dropped the “unsafe” keyword.

 

Also, I learned:

·         Static Methods cannot be in an interface

·         Internal Methods cannot be in an interface

·         I dropped Abstract b/c the code had references to its own instance

TFS

I installed TFS on my local machine for version control and build services.  I got the version control working fine – using a MAIN/DEV/PROD branching strategy.  The problem is setting up the builds.  I installed the Build Server and Agent no problem on the local machine.  Then wanted to associate current Team Project Collection to the Build Controller:

 

However, when I went to the Build Controllers – there is no button to add it to the available list.

 

 

I decided to stop – b/c I really don’t need CI for my local workstation but I was getting excited to alter the build steps using WF4.0 – just to see it in action.

 

Looks like you need to install the Build Controller BEFORE you create a Team Collection – there is no way to retro-add a collection to a controller?  I Binged the error and no one has answered it (yet).  I also tried to alter the properties of the Build Server in TFS Explorer and cannot alter the url:

Humm, perhaps an enhancement for later…