Showing posts with label unit testing. Show all posts
Showing posts with label unit testing. Show all posts

Monday, June 3, 2019

Unit testing with jUnit5 and Mockito

Mocking for Spring injected dependencies

import org.junit.jupiter.api.Test;

@ExtendWith(MockitoExtension.class)
class Person {
   @Mock
   DependencyA dependencyA;

   // Don't use @InjectMocks if using constructor injection with final dependencies.
   // Mockito can't set the new mocks for each test
   TestedClass target;

   @BeforeEach
   public void setup() {
      // only needed if you do Mockito.when(dependencyA.methodAbc()).thenReturn() or similar
      MockitoAnnotations.initialize(this);  
      target = new TestedClass(dependencyA);
   }

   @Test
   public void testMethodWhatsyourname() {
      // given
      ...
      
      // when
      target.whatsYourName();

      // then 
      ...
   }
}

Thursday, September 3, 2009

Using FlexUnit to Unit Test Cairngorm Visual Objects

Introduction
In a RIA application a typical split of the source code (counted by code size, in bytes) is as follows:
  • 45-60% - client: visual objects like views and their sub-components with their logic
  • 15-20% - client: non-visual objects (primarily Cairngorm worker-to-service piping)
  • 30-35% - server: middle-tier code
In the couple medium-size business application, I have analyzed, the middle-tier was implemented in Java and the client was implemented in Flex using the Cairngorm architecture. So, I don't have verified numbers for other RIA configurations.

If we are determined to use TDD or simple just provide automated tests for our application and get the most coverage for the effort required to develop these tests, it seems we could use the following testing methodologies:
  • FlexUnit testing for the client, especially the client's visual objects
  • FlexMonkey tests for whole client's features
  • jUnit tests for the middle-tier code.
I another blog, I will touch on the FlexMonkey. In this one, I'd like to present how we can unit test the visual layer of the client using the FlexUnit framework. jUnit testing is well described in many other sources.

Testing Scenario
In the spirit of Cairngorm, a UI user gesture is directed to a handler which creates a Cairngorm message, attaches a payload to it (any relevant information) and dispatches it (event.dispatch()). Our test will mimic a user gesture (click a button) and will try to catch the dispatched Cairngorm event and verify its payload. We're using Flex 3 (ver. 3.2) and FlexUnit 4 beta 2.

Sample Application
To explain the topic, I'll be using the following sample application. The view (Main.mxml adds it to the ViewStack) is (to see the code in a new window, move your mouse pointer over the code and click the left of the icons that appear in upper-right corner):
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300">

<mx:Script source="MyViewScript.as" />

<mx:HBox verticalAlign="middle" >
<mx:Text id="txtValue" text="Entry:" />
<mx:TextInput id="entryTextInput" />
<mx:Button id="btnSave" label="Save" click="onBtnSaveClick(event)" />
</mx:HBox>

</mx:VBox>

The script used bu the view is:
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;

public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

public function onBtnSaveClick(event):void
{
trace("clickHandler detected an event of type: " + event.type);

var entryVO: EntryVO = new EntryVO();
entryVO.text = entryTextInput.text;

var saveEvent: SaveEntryEvent = new SaveEntryEvent(entryVO);

saveEvent.dispatch();
}


and the TestRunner class to run the test is
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
xmlns:business="gov.olcc.fishbait.business.*"
xmlns:control="gov.olcc.fishbait.control.*"
xmlns:view="gov.olcc.fishbait.view.*"
layout="vertical"
width="100%" height="100%"
creationComplete="runTests()">

<mx:Script>
<![CDATA[
import com.adobe.cairngorm.control.FrontController;
// import gov.olcc.fishbait.view.TestFishBaitView;
import gov.olcc.fishbait.view.MyView;
import org.flexunit.runner.FlexUnitCore;
import org.flexunit.flexui.TestRunnerBase;
import gov.olcc.fishbait.view.MainTest;
// import gov.olcc.fishbait.view.TestFishBait;

//Add an import statement(s) for the class(es) under test
private var core: FlexUnitCore;

private function runTests():void
{
core = new FlexUnitCore();
core.addListener(testRunner);
core.run(MainTest);
}

]]>
</mx:Script>

<!-- Cairngorm Controller and Service Locator -->
<control:FishBaitController id="controller" />
<business:Services id="services" />

<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
</mx:Application>

The trick is to be able to catch the Cairngorm event. What is not obvious, the event.dispatch() method uses a CairngormEventDispatcher, so we need to add our listener to it. The resulting test code is
package gov.olcc.fishbait.view {
import com.adobe.cairngorm.control.CairngormEventDispatcher;
import flash.events.MouseEvent;
import gov.olcc.fishbait.events.SaveEntryEvent;
import gov.olcc.fishbait.model.ViewModelLocator;
import gov.olcc.fishbait.vo.EntryVO;
import mx.automation.codec.AssetPropertyCodec;
import org.flexunit.Assert;
import org.fluint.uiImpersonation.UIImpersonator;
import org.flexunit.async.Async;

public class MainTest {
var myView: MyView;
public var modelLocator:ViewModelLocator = ViewModelLocator.getInstance();

[Before(async,ui)]
public function setUp():void {
myView = new MyView();
UIImpersonator.addChild(myView);
}

[After(async,ui)]
public function tearDown():void {
UIImpersonator.removeChild( myView );
}   

[Test(async,timeout="3000")]
public function testOnBtnSaveClick():void {
CairngormEventDispatcher.getInstance().
addEventListener(SaveEntryEvent.SAVE_TEXT,
Async.asyncHandler( this, handleTestOnBtnSaveClick, 3000 ),
false,0,true);

myView.entryTextInput.text = "Test Text";
var clickEvent: MouseEvent = new MouseEvent(MouseEvent.CLICK);
myView.btnSave.dispatchEvent(clickEvent);
}

private function handleTestOnBtnSaveClick(event:SaveEntryEvent,
passThroughData:Object):void {
var entry:EntryVO = event.text;
Assert.assertEquals("Test Text", entry.text);
}
}
}

Other points about this test:
  • We use FlexUnit UIImpersonator as a parent to our view. Without adding a view to a parent, the UI controlls are not initialized and can't be used.
  • To get the instance of the CairngormEventDispatcher, we use its static mathod getInstance().
  • Since the actual test happens in the event handler, we need to user an annotation [Test(async,timeout="xxx ms"] to request the Async support for the test.
  • Then, instead of providing just the handler method as an argument to the assEventListener(), we wrap this method in Async.asyncHandler(), which will wait for the handler to be called unless the handler will not be called within specified time, in which case the test will fail.
And this is it. Enjoy testing Cairngorm visual objects.

Tuesday, August 18, 2009

Using FlexUnit 4 with Flex 3: Sample Application

Introduction
We had hard time finding on the internet a sample like this. So, here's ours. Additional steps required for this test to be run:
  • download FlexUnit 4 from their site.
  • add the FlexUnit swc files to the project's classpath
  • copy the sources below into your project and adapt them (use the view source icon in each source code frame below to view/copy the source code).
  • once everything is on place, right click on the TestRunner and select Run Flex Application.
At the end of the article, we have added some notes about using FlexUnit with FlashBuilder 4 and Flex 4
Enjoy! It's a great tool!

File structure

Tested Object

package olcc.account
{
public class Account
{
public function Account(){
}

private var balance:Number=0;

public function deposit(amount:Number): void {
balance=balance+amount;
}

public function withdraw(amount:Number): void {
balance=balance-amount;
}

public function getBalance():Number {
return balance;
}
}
}
Test Suite (Optional)

package olcc.account
{
import org.flexunit.runners.Suite;

[Suite]
[RunWith("org.flexunit.runners.Suite")]
public class MyTestSuite
{
public var t1: AccountTest;

}
}


Unit Test

package olcc.account
{
import org.flexunit.Assert;

public class AccountTest
{
[Test]
public function testNew():void {
var account:Account = new Account();
Assert.assertEquals("Expecting zero account balance", 0, account.getBalance());
}

[Test]
public function testDeposit():void {
var account:Account=new Account();
account.deposit(50);
Assert.assertEquals("Balance on a new account after 50 deposit is 50",50,account.getBalance());
account.deposit(25);
Assert.assertEquals("Balance after 50 deposit and another 25 deposit is 75", 75,account.getBalance());

}

[Test]
public function testWithdraw():void {
var account:Account = new Account();
account.deposit(100);
account.withdraw(50);
Assert.assertEquals("Balance should be: + $100 - $50 = $50",50,account.getBalance());
}
}
}


Test Runner
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="*"
xmlns:flexunit="http://www.adobe.com/2009/flexUnitUIRunner"
creationComplete="onCreationComplete()">

<mx:Script>
<![CDATA[
import org.flexunit.runner.FlexUnitCore;
import org.flexunit.flexui.TestRunnerBase;
//Add an import statement(s) for the class(es) under test
import olcc.account.MyTestSuite;

private var core: FlexUnitCore;

private function onCreationComplete():void
{
core = new FlexUnitCore();
core.addListener(testRunner);
core.run(MyTestSuite);
}
]]>
</mx:Script>

<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" />
</mx:Application>

Using FlexUnit 4 with Flex 4

Flex 4 beta2 has support for FlexUnit, and the most recent version of it which is version 4.0. If you go to the New->TestCase menu, FlashBuilder can create for you a whole test class. And add to the flex build path the necessary libraries. This is done pretty well. But when I tried to apply the simple test application presented above to a Flex 4 application, I ran into multiple problems. One critical, as of today, was the issue that the AsDoc for Flex 4 is not available, nor much of the documentation for it. So, some classes from FlexUnit 4 that I needed (like TestRunnerBase), I wasn't able to find. Until these issues are resolved in Flex 4, I decided to use the FlexUnit 4 directly. To do this, I removed the Flex 4 libraries from the build path and added the FlexUnit 4 beta 2 libraries (.swc files). In general, the flex parser is not always stable, which showed up in this exercise and I had a compilation error that shows every other time I compile my TestRunner.mxml (with the same source code), but I can run the tests. Simply, I made sure that the last compilation is a clean one. Also, closing and reopening the project eliminated this issue.

Wednesday, May 20, 2009

Using Unit Testing to Test GWT RCP Calls

This is a short note. I'm working on a GWT application and ran into a problem with an RPC call which gets some objects from the database using Hibernate and passes them back to the client. I'm going to solve the problem using Dozer, but I needed to confirm this was the problem and simplify the testing of this in future. So, I decided I want to unit test this service from the client's perspective. Here are my notes from this exercise:
  • The easiest way to create a GWTTestCase is using the GWT's jUnitCreator. Creating it by hand is possible but tricky.
  • The asynchronous test needs to use delayTestFinish(delayMs) and finishTest(). In my case, I had to set 5000 Ms. For some reason, 500Ms, which I thought would be more than enough was timing out.
  • The good news is, that when using Eclipse plugin for GWT, starting initiating Run as JUnit Test on the GWTTestCase test starts for you also the server. And doing the same with Debug as JUnit Test allows to debug the client as well as server code.
Note: the similar test is supported in Flex application!