Ben Biddington

Whatever it is, it's not about "coding"

Posts Tagged ‘tdd

RSpec — common base specs

leave a comment »

Sometimes I am fond of creating inheritance chains for tests, which is easy in Java or C# say, but not quite as obvious in rspec.

Define and register a base class

It just needs to inherit from Spec::Example::ExampleGroup so it’s runnable.

require 'spec/example/example_group'
class UnitTest < Spec::Example::ExampleGroup
   protected
   def you_can_call_this
   end
end

Spec::Example::ExampleGroupFactory.register(:unit_test, UnitTest)

Set the type when describing

describe 'By supplying the :type', :type => :unit_test do
    it 'this example group inherits from whatever class you supply as :type' do
        self.protected_methods.should include('you_can_call_this')
    end
end

You now have common base class to your specifications.

Written by benbiddington

6 November, 2010 at 13:37

Posted in development

Tagged with , ,

Test driving and test coverage

leave a comment »

Yesterday I enabled rcov on my current project and was surprised that it had 100 per cent unit test coverage.

But perhaps I should not have been surprised. After all, if you are truly test driving, how could you possibly leave anything uncovered?

Written by benbiddington

7 October, 2010 at 13:37

Posted in development

Tagged with ,

Raking .NET projects in TeamCity

leave a comment »

Faced with the unpleasant prospect of assembling yet another stack of xml files for an automated build, I thought I’d try rake instead. A couple of people here at 7digital have used Albacore before, so I started there.

1. Build

Use Albacore‘s msbuild task:

require 'albacore'

desc "Clean and build"
msbuild 'clean_and_build' do |msb|
    msb.properties :configuration => :Release
    msb.targets :Clean, :Build
    msb.verbosity = "quiet"
    msb.solution  = "path/to/ProjectName.sln"
end

2. Run tests

This is also very straight forward with Albacore, but slightly more useful is applying the usual TeamCity test result formatting and reporting.

2.1 Tell your build where the NUnit test launcher is

TeamCity already has an NUnit runner, and the recommended way to reference it is with an environment variable.

Note: The runners are in the <TEAM CITY INSTALLATION DIR>/buildAgent/plugins/dotnetPlugin/bin directory.

2.2 Write the task

Once you have the path to the executable, you’re free to apply any of the available runner options.

Assuming you have added the TEAMCITY_NUNIT_LAUNCHER environment variable then the actual execution is then something like:

asm = 'ProjectName.Unit.Tests.dll'
nunit_launcher = ENV["TEAMCITY_NUNIT_LAUNCHER"]
sh("#{nunit_launcher} v2.0 x86 NUnit-2.5.0 #{asm}")

Beats hundreds of lines of xml I reckon.

References

Written by benbiddington

18 February, 2010 at 13:37

Posted in development

Tagged with , , , , , ,

Scala introduction — writing an OAuth library

leave a comment »

I started out intending to write some scala examples against the twitter API, however I soon discovered I needed OAuth first. Given that I use OAuth all the time at work I figured I could probably do with learning about it first-hand, while learning scala.

org.junit.rules._

I chose to test drive it with JUnit 4.7 and NetBeans.

NetBeans works almost immediately with scala, and has support for project templates etc — even scala JUnit fixtures.

UPDATE (2010-04-27) I have since discovered IntelliJ to be much better, and there is now a free community edition. IntelliJ supports scala without any fiddling around.

JUnit mostly works, though rules don’t and neither do some matchers. Even though rules don’t work, I have included it anyway because I have the t-shirt.

You can find the project on github.

Important abstractions

  1. SignatureBaseString.
    1. Characterized by three ampersand-separated segments: verb, uri, parameters.
    2. URL Encoding must conform to RFC 3986, and the following characters should are consider unreserved so should not be encoded:
      ALPHA, DIGIT, ‘-‘, ‘.’, ‘_’, ‘~’
  2. Signature.
    1. Signature is a keyed-Hash Message Authentication Code (HMAC).
    2. Consumer secret required part of HMAC secret key.
    3. Token secret is optionally included in HMAC secret key:
      (consumer_secret, token_secret) => uri_encoded_consumer_secret&[uri_encoded_token_secret]
  3. OAuthCredential. Represents the secret key(s) used to create the HMAC signature. OAuth requires a consumer credential, and optionally a token credential, representing the end user.

Now that these core concepts are complete, I am working on high-level policy, like classes for generating signed URLs and authorization headers.

Notes

JUnit — expecting exceptions in scala

Assuming JUnit 4.x, a test can expect an exception using the test annotation:

Java:

@Test(expected=IllegalArgumentException.class)
    public void ExampleThrowsException(){
        throw new IllegalArgumentException();
    }

This needs to be modified for scala:

Scala:

@Test { val expected=classOf[IllegalArgumentException] }
    def ExampleThrowsException {
        throw new IllegalArgumentException
    }

The reason for it is outlined here in the Java annotations section on named parameters.

Here is the documentation for scala annotations. Seealso: the documentation for scala 2.7.3 (includes dbc).

Closures and return

The return statement immediately returns from the current method, even if you’re within a closure. Omit return in this case — return is optional anyway.

When to use semicolon line terminator

Never — apart from:

  • When a method returns Unit (equivalent to void) and you aren’t using return keyword. [TBD: Add example].

How to use blocks

var count = 1
times(2) { println("Printed " + count + " times")}
protected def times(count : Int)(block : => Unit) = {
    1.to(count).foreach((_) => block)
}

Seealso: some executable examples on github

References

ALPHA, DIGIT, '-', '.', '_', '~'

Written by benbiddington

18 September, 2009 at 13:37

Posted in development

Tagged with , , , , , , , ,

Particle physics, mocks and stubs

leave a comment »

Steve Freeman had interesting analogy in TDD 10 years later (17m30s, slide 26: The origins of mock objects). He describes mocked unit test being “rather like particle physics”.

You fire something at a particle, things splinter off and you can detect what happens…

mocks-and-stubs

A mock is used to both detect the emissions from the system under test (SUT), and verify expectations. Additionally, a mock object may perform stub duties. This doesn’t quite fit, since fission is one-way.

Testing “by detection” like this is considered behaviour verification: verifying collaborations between the SUT and other objects.

To be testable in such a manner:

  • Requires the ability to isolate the SUT sufficiently, i.e., detach it completely from its context and collaborators. A test fixture should be able to create the SUT easily by itself.
  • Then the SUT should minimize concrete dependencies.
  • Collaborators must be designed in such a way to allow a mock to be generated that can intercept interactions. This means identifying the abstraction(s) for collaborators.
  • Mock is a stub in the sense that it needs to stand in for a real (if inert) object. But a mock is also a “detector” and is used as the means of assertion.
  • Stub queries and mock actions. “we mock when the service changes the external world; we stub when it doesn’t change the external world – stub queries and mock actions”

References

Written by benbiddington

12 September, 2009 at 15:15

Posted in development

Tagged with , , , ,

RhinoMocks — repeat times

with one comment

My pair and I discovered some unexpected behaviour with repeat times yesterday. It appears repeat times behaves differently when using the Expect than it does when using AAA.

Our expectation fails, i.e., the following test passes, when the actual number of invocations exceeds expected:

[Test]
public void expect_repeat_n_times_does_not_work_when_actual_greater_than_expected() {
    const Int32 ActualTimesToCall = 6;
    const Int32 ExpectedTimesToCall = 4;

    var mock = MockRepository.GenerateMock<IExample>();
    mock.Expect(example => example.ExampleMethod()).Repeat.Times(ExpectedTimesToCall);

    for (var i = 0; i < ActualTimesToCall; i++) {
        mock.ExampleMethod();
    }

    // [?] This one passes
    mock.VerifyAllExpectations();
}

And yet when using AAA, we get the desired outcome (the following test fails):

[Test]
public void aaa_repeat_n_times_does_work_when_actual_greater_than_expected() {
    const Int32 ActualTimesToCall = 6;
    const Int32 ExpectedTimesToCall = 4;

    var mock = MockRepository.GenerateMock<IExample>();

    for (var i = 0; i < ActualTimesToCall; i++) {
        mock.ExampleMethod();
    }

    // This one fails (as expected)
    mock.AssertWasCalled(
        example => example.ExampleMethod(),
        options => options.Repeat.Times(ExpectedTimesToCall)
    );
}

Produces the message:

Rhino.Mocks.Exceptions.ExpectationViolationException: IExample.ExampleMethod();
Expected #4, Actual #6.

As expected.

The happens because of AbstractExpectation.CanAcceptCalls stops recording after range max has been reached, and so the actual number of calls recorded is never greater than the expected number:

// AbstractExpectation
public bool CanAcceptCalls
{
    get
    {
        //I don't bother to check for RepeatableOption.Never because
        //this is handled the method recorder
        if (repeatableOption == RepeatableOption.Any)
            return true;

        return expected.Max == null || actualCallsCount  > actualCallsCount )
            return false;

        if (Expected.Max==null)
            return true;

        // BJB: The following is always true
        return actualCallsCount <= expected.Max.Value;
    }
}

Solution?

I have been advised by someone on the Google group to use AAA syntax instead. And it is nicer to be sure — if a little less discoverable.

AAA and methods that return values

Expect is overloaded to handle return values — it supports Action<T> and Func<T, TReturnValue>. AssertWasCalled on the other hand does not support Func<T, TReturnValue>, so we have to suppress the return value manually in the function:

Stream mockStream = MockRepository.GenerateMock<Stream>();
mockStream.Expect(stream => stream.CanRead).
    Return(true).
    Repeat.Once();
...
mockStream.VerifyAllExpectations();

Becomes something like:

Stream mockStream = MockRepository.GenerateMock<Stream>();
...
mockStream.AssertWasCalled(
    stream => { var temp = stream.CanRead; },
    options => options.Return(true).Repeat.Once()
);

Written by benbiddington

23 June, 2009 at 08:50

Mocking and interception

leave a comment »

I have Just been having a look at Moq vs RhinoMocks with respect to mocking concrete members. 

Looks like with either alternative we can mock whatever type we like, however expectations can only be set on certain types of operations on unsealed classes: virtualabstract or interface.

Moq uses Castle Dynamic Proxy which has the limitation:

You can use DynamicProxy to generate lightweight proxies on the fly for one or more interfaces or even concrete classes (but only virtual methods will be intercepted).

Hence only virtualabstract or interface operations can be invoked on a mocked instance. 

The reason for this as described by Daniel Cazzulino:

it’s a limitation of the CLR since its inception: there’s no built-in interception mechanism. so, the interception mechanism we use is auto-generated classes that inherit from the types to mock, and override all members to provide the interception. that’s why they need to be virtual. we’re reusing the interception library from Castle DynamicProxy for doing that. 

Rhinomocks is subject to the same limitation (see Capabilities section):

Attention: Rhino Mocks can only mock interfaces, delegates and virtual methods of classes! (Although it is possible to get work around existing code and easily apply Rhino Mocks, see Example of testing an abstract class)

For example, invoking the following:

MockRepository mocks = new MockRepository();
Artist list = mocks.StrictMock();

// Setup the expectation of a call on the mock
Expect.Call(list.ArtistId).Return(999);
mocks.ReplayAll();

// Evaluate the values from the mock
Assert.AreEqual(999, list.ArtistId);
mocks.VerifyAll();

Results in an error: 

Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).

And mocking an abstract class requires slightly more work.

Mocking System.Object with Rhino Mocks

The following snippet fails:

MockRepository mocks = new MockRepository();
Object mockObject = mocks.StrictMock();

Expect.Call(mockObject.Equals(null)).Return(false);

mocks.ReplayAll();

With exception:

Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).

And yet if I create a type, have it extend System.Object and override GetHashCode:

public class ObjectWrapper : Object
    {
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

 

then that same snippet works. Is this related to the mscorlib thing that TypeMock has?

Written by benbiddington

31 October, 2008 at 09:33