Custom test runner for FlexUnit 4 and mock-as3

Brian LeGros | August 6th, 2009 | programming  

At the August Adogo meeting, I presented on the new features coming in FlexUnit4 and mock-as3. During the presentation, I showed the following sample (which has been updated) of how a FlexUnit 4 test using a customer runner for mock-as3 would work. Please keep in mind the example is a bit contrive but exemplifies the configuration options for the runner.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package us.adogo.mock
{
   import com.anywebcam.mock.Mockery;
 
   import org.flexunit.Assert;
   import org.flexunit.assertThat;
   import org.hamcrest.core.not;
   import org.hamcrest.object.equalTo;
   import org.hamcrest.object.hasProperty;
   import org.hamcrest.object.nullValue;
 
   [RunWith("com.anywebcam.mock.runner.MockAs3TestRunner")]
   public class ExampleUsingMockAs3Runner {
      public var mockery : Mockery;
 
      [Mock]
      public var user : User;
 
      [Mock(inject="false")]
      public var account : Account;
 
      private var controller : UserController; 
 
      [Before]
      public function setUp() : void {
         account = mockery.nice(Account, ["1234567890"]) as Account;
         this.controller = new UserController(); 
      }
 
      [Test]
      public function testAddUserWithUsernameAndPasswordOnly() : void {
         //setup mock
         mockery.mock(user).method("save").calls(function () : void {
            user.id = 1;
         }).once;
 
         //populate object properties as you usually would
         user.username = "bobdobbs";
         user.password = "mysecret";
 
         //execute my controller method being tested
         controller.addUser(user);
 
         //test that the currentUsers went up by one and that its id is 1
         assertThat(controller.currentUsers.length, equalTo(1));
         assertThat(controller.currentUsers.getItemAt(0).id, equalTo(1));
         assertThat(controller.currentUsers.getItemAt(0).username, equalTo("bobdobbs"));
         assertThat(controller.currentUsers.getItemAt(0).password, equalTo("mysecret"));
      }
 
      [Test]
      public function testValidateUserAccount() : void {
         //setup mock
         mockery.mock(account).method("isValid").withArgs(User).returns(true).once;
 
         //execute my controller method being tested
         var expected : Boolean = controller.validateUser(new User(), account);
 
         //test that the account is valid
         Assert.assertTrue(expected);
      }
 
      [Test(verify="false")]
      public function testDefaultUserSize() : void {
         assertThat(controller, hasProperty("currentUsers"));
         assertThat(controller.currentUsers, not(nullValue()));
         assertThat(controller.currentUsers.length, equalTo(0));
      }
   }
}

This evening I updated the Adogo SVN with a working version of this runner and thought I’d detail its initial implementation.

  • To use the runner place the metadata [RunWith("com.anywebcam.mock.runner.MockAs3TestRunner")] on the test class’ declaration.
  • Once annotated with metadata, the test class will not run unless a public variable, or setter, is available of type com.anywebcam.mock.Mockery. This will allow the runner to inject a Mockery object and prepare() the mockery to produce mock objects. Using and preparing a mockery is a new requirement for mock-as3 if you’re utilizing type-safe mocks due to the asmock integration.
  • Any public variable, or setter, annotated with the metadata [Mock] will have a type safe version of it injected automatically prior to the execution of each test method. By default a nice mock will be used, but if you specify the “type” attribute (e.g. – [Mock(type="strict")]) as “strict” then a strict mock will then be used. The difference between nice and strict mocks, is the equivalent of the “ignoreMissing” constructor argument on com.anywebcam.mock.Mock being set to true, or false, respectively.
  • If the [Mock] metadata is used on a class with a constructor requiring arguments, whether they are optional or …rest, the runner cannot automatically inject the mock due to a limitation in its underlying dependency on the asmock library. If you need a mock object instance using constructor arguments, set the attribute “inject” as false (e.g. – [Mock(inject="false")]. Doing so will tell the runner that you’re going to use the mock-as3 framework directly to create the mock. The ideal place to do this in your test is within the [Before] methods defined for the test class. By going through all this hoopla, you get automatic mock prepration and verification, just as with the automatically injected mock objects.
  • After the execution of each test method, the runner will automatically call verify() on each object variable/property marked with the [Mock] metadata. If you’d like to disable verify() from being called on all mocks for a test method, simply add the attribute “verify”, with a value of false, to your [Test] metadata (e.g. – [Test(verify="false")]). This can be helpful if you want the runner to inject the mockery and all of your mocks, but you would like to specify which mocks are verified for the test.
  • Currently this runner requires FlexUnit 4 Beta 2 and a custom build of mock-as3 to work as stated. You can find SWCs for each in the Adogo August project linked above.

What’s important to note, is that this runner is more restrictive than using the mock-as3 framework directly, so it may not suite your needs. I based this runner off of concepts I saw in the JMock runner for JUnit 4, the @Mock annotation found in Mockito for Java, and my own testing practices. If anyone finds time to play with it and you find any gremlins, let me know. In speaking with Drew, it looks like this may make it into the next release of mock-as3 along with a couple of other cool features, so I hope people find it helpful.

UPDATE: Drew has been kind enough to deploy this FU4 test runner to the mock-as3 SVN repository under the class name com.anywebcam.mock.runner.MockRunner. Please use this copy for future reference. Please also note this version will only work with FlexUnit4 Beta2 and earlier. FlexUnit4 RC1 has changed the implementation for test runners and this code will need to be updated.

FlexUnit 4 public alpha now available

Brian LeGros | May 4th, 2009 | news  

Just a quick note. Last night the Mike did a blog post on the new features coming to FlexUnit and the working title of FlexUnit 4 for the project. You can find the blog post @ http://blogs.digitalprimates.net/codeSlinger/index.cfm/2009/5/3/FlexUnit-4-in-360-seconds. There is a link to the alpha in the post and as soon as it’s available on Adobe’s servers, we’ll publish that URL as well. Keep in mind that it does support legacy FlexUnit and Fluint tests, so dig in and let us know what you think!

FlashCamp Orlando 2009 Registration Open

Brian LeGros | May 3rd, 2009 | news  

A little belated, but registration for FlashCamp Orlando 2009 opened this weekend with early bird expiring on May 1st at $35. Fear not though, the standard registration price is a mere ~$50 which, IMO, is a significantly small fee to attend a one day event.

FlashCamp (formerly FlexCamp) is a one-event day sponsored by Universal Mind and Adobe in which developers and designers can take a deep dive into topics ranging from introductory to advanced from the Flex world. This year Adogo’s very own Maxim Porges and Jason Madsen will be presenting along side Greg Wilson, of Adobe, as well as David Tucker, Andrew Powell, and Christian Saylor, of Universal Mind, and Carl Smith from nGenWorks. The event will take place on May 29th from 8:30 AM to 5:30 PM. Registration includes free parking, lunch, door prizes and lots of great networking.

If you have the time available, I definitely suggest signing up for a spot, availability is limited. I won’t be able to attend, or speak at, the event since we’ll be welcoming our 1st child into the world this month, but I would definitely be there otherwise. Hope you can make it out!

New FlexUnit … what?

Brian LeGros | May 3rd, 2009 | news  

Mike Labriola today announced on the Fluint Discussion group the big news a few in the Fluint team have been sitting for months now. The Fluint team is leading an OSS initiative to create the next version of the FlexUnit product. What’s great about this initiative (as Mike outlines on the mailing list) is that the new version of Fluint has been designed to mimic a lot of the conventions found in JUnit 4 while still addressing all of the problems Fluint solves for us in the Flex world. I know, for me, this means being more productive when writing tests and finally having better tooling when working with Flex. Here are some of the features listed from Mike’s email:

  • Metadata based Test and Suite identification (no more need to extend testcase or testsuite)
  • Hamcrest matchers courtesy of the hamcrest-as3 project.
  • Theories, DataPoints and Assumptions
  • Ignorable tests
  • Enhanced Sorting and Filtering
  • Custom runner integration

Probably one of the coolest part of this entire framework thus far is that last item. The Fluint team has already been able to successfully run legacy unit tests from the current versions of FlexUnit and Fluint. This means that you can have hybrid suites of tests in the new FlexUnit (e.g. -FlexUnit, Fluint, FUnit, asunit, etc) making migration between frameworks relatively simple.

We’re going to be launching a public alpha release in the near future, but we are still continuing work on Fluint at least as far as release 1.2 (1.1.1 was release yesterday). Please keep in mind however, the goal is for FlexUnit to become what would have been Fluint 2.0. Look for more details in the coming weeks.

Here’s to better testing!

FlexCamp Miami Tomorrow

Brian LeGros | March 5th, 2009 | conferences  

FlexCamp Miami is tomorrow, 03/06/09. If you find yourself without something to do tomorrow, jump in the car and join us in the Hurricane Room at the Bank United Center on the UM Campus. We’ll be starting around 8:00 AM and should finish up around 5:00 PM; lunch is included. If you’d like to attend, just hop over to their EventBrite page and register. We’ve got some great speakers including Greg Wilson, David Tucker, Andrew Powell, Laura Arguello, Christian Saylor, Jeremy Grelle, along with Max and myself from the Adogo.

Hope you can make it!

More updates about the new Brevard user group

Brian LeGros | July 20th, 2008 | programming  

Well, after some searching, I’ve decided to give House of Joe on 192 next to the Melbourne mall a shot for the first meeting of the Brevard user group I’m trying to start. It’s open until 11:00 PM on weekdays and has free wifi, so hopefully it’ll work out. Thanks to Sebastian for the suggestion.

I’ve been doing some thinking about the focus on the group. I’ve decided that rather than focusing exclusively on Adobe technologies, I’d like to shift the focus to rich internet technologies (RIA) including Flex, AIR, AJAX, and possibly Silverlight. I’ve been messing a lot with jQuery recently, and just like the rest of the masses, I can’t get enough of it; I’m sure there are others that feel the same way too. There are other cool APIs that’d I’d like to mess with including the spread over at Google (Data, Charts, Maps, etc.) that can fall under the umbrella of the RIA buzzword as well.

Based on the audience I’ve seen in Brevard and the types of jobs I see advertised on the job boards, I think this type of group will have a better chance at growth than just an Adobe focused group. My next goal is to pick a day and time that we can meet, then the first meeting’s topic, then a hopefully a domain and website. Initially I’m going to focus on just meeting up with people and hacking away at code, but if we get more people joining us, then maybe we can start doing presentations too.

Keep a look out for more info as I continually try to get my act together, and fail at doing so. ;)

Anyone interested in an Adobe group in Brevard?

Brian LeGros | July 7th, 2008 | programming  

As the Adogo has grown over the last year, I’ve noticed that a few people, like myself, make the trek from the Space Coast into Orlando for our monthly meeting. In an effort to bring the work of the group to Brevard County, I was wondering if anyone would be interested in participating in an Adobe group locally? Initially I’d be interested in just getting together a local coffee shop or pub and doing hackfests with Flex, ColdFusion, AIR, and whatever else we can get our hands on. As attendance grows, maybe we could get into presentations, but until then, I’d like to keep it layback. I’m still looking to stay involved in the Adogo, but who can turn down getting away and coding for a few hours each month.

I’m looking for spots to have the meeting still, but things close pretty early in the Melbourne area; does anyone have any ideas about good joints that could support us? I’m looking into Charlie and Jake’s in Suntree or possibly the Sun Shoppe Cafe (coffee shop) in downtown Melbourne. I’d love find something beachside, but I’m not sure where to look. If people are interested we also need to come up with a name, date, and time. Any suggestions?

As I put together more information, I’ll post about them here. Please comment and let me know if you would attend. Check back soon for more details.

Help with Introspection using ActionScript 3

Brian LeGros | April 12th, 2008 | programming  

Ok, I need help. I’ve been able to discover the coolness that is getQualifiedClassName() and getDefinitionByName() and describeType() when it comes to working with introspection/reflection in ActionScript 3. I am stuck however. I want to get a hold of all the class names available in the compiled Flash movie at runtime. I’m writing a library that will look for custom metadata on classes and associate functionality with the classes (or possibly objects) if they are annotated in a specific way. Right now, short of asking for a list of those classes from the developer, I don’t know of a way to build a bootstrap function/class that will introspection into the Flash movie and get me a list of them. I was thinking maybe if I could find a way to programmatically access the manifest file that would work, but again I can’t find a way to do that.

Does anyone know how to do this or am I doomed to introspecting on objects and programmer declared references rather than classes?

UPDATE: I found a feature request in the Flex 3 JIRA database. Basically it’s not in Flex yet, nor is it supported by the Flash movie, but 4 people have voted for the feature thus far. That being said, please vote for this feature so we can get one of the final pieces to reflection built into Flex. BTW – If anyone wants questions answered with regards to Flex, check out the flexcoders mailing list over on Yahoo. Everyone probably knows about it but I’m slow.

acts_as_conference 2008 : Rails on AIR

Brian LeGros | February 9th, 2008 | conferences  

Peter Armstrong, author of Flexible Rails, gave this presentation which focussed on how Flex and AIR can consume REST’ful resources. Peter unfortunately had a hard drive crash about an hour before his presentation so needless to say his presentation didn’t go as planned. Although he didn’t really have any slides (because they were all destroyed) he was able to borrow the laptop of a fellow conference go’er and show us some code examples.

The code examples were geared towards introducing MXML and Actionscript to Rails developers. I feel pretty comfortable with both, but it’s always good to see different approaches to coding in Flex, especially code using HTTPService since I spend more time using RemoteObjects. I would have liked to seen, if only mentioned, the topic of component development (visual and non-visual) and data binding, but I can understand why it was omitted since most Rails developers aren’t familiar with UI practices other than your standard web stack.

Towards the end of the presentation, Peter revealed Ruboss, a Flex framework built specifically for consuming REST’ful resources. Ruboss uses a controller to expose an Actionscript interface to translate CRUD operations to their REST’ful equivalents. He said he’s going to be releasing it over the next few weeks under his new company, so watch Ruboss.com for more details.

We’ve asked Peter to give a Connect presentation at an Adogo meeting later this year on Flex/AIR and Rails. The Orlando community can definitely benefit from Peter’s work with Flex/REST and we hope to pimp that to its fullest … j/k Peter, keep up the great work.

January Adogo Meeting – Flex 3 Pre-release Tour with Ben Forta

Brian LeGros | January 5th, 2008 | news  

For those who aren’t following the Adogo blog, the January meeting promises to be a good one as we have been chosen by Adobe to be the only stop in Florida for the Flex 3 Pre-release Tour. For our leg of the tour we are extremely fortunate to have Ben Forta, Senior Technical Evangelist for Adobe, as our guest speaker. We’re going to be giving away tons of schwag as well as some pretty nice software licenses. We’re getting to use a conference room at Westgate Lakes thanks to the Porges and are going to have Pizza Hut cater most likely.

I’m really proud of all the work we’ve done at the Adogo (Adam, Max, and myself) and getting Orlando as a stop on this tour helping to affirm that. In the few months since last August, we have been able to create the beginnings necessary to revitalize the Adobe community in the Orlando area. We still have a lot of work to do to get the word out, but we’ve got a good foundation to build on.

Hope to see everyone at the next meeting (January 21st @ 7:00 PM at Westgate Lakes near the Smokehouse)!