Please disable your adblock and script blockers to view this page

Search this blog

Showing posts with label Model. Show all posts
Showing posts with label Model. Show all posts

Monday 21 January 2019

Unit testing of ADF Application using JUnit

 JUnit is a unit testing package for Java language and can be used to test Oracle ADF applications as ADF is built on top of the J2EE framework. Unit testing is basically is a process to verify the smallest testable module against some defined test criteria. Here I am going to illustrate how can we set up and use JUnit in JDeveloper 12.2.1.3 to test the ADF application.

JDeveloper 12.2.1.3 comes with a JUnit extension so no need to install it separately. Let's start by creating a Fusion Web Application in JDeveloper IDE. Here I am taking Departments table of default HR Schema to prepare the model for ADF Application.




The next step is to create a new project to hold unit tests so that the whole application doesn't look ambiguous. Right-click on the Application name and select New–> From Gallery–> General–> Projects --> Java Project 



Put a name for that project and click on the Finish button.



Now next step is to create a Test Suite for business components and before that, we should know some terminology that is used in unit testing.

Test Suite- A group of Test Cases

Test Fixture- A class to handle long-running test cases and keep the state of multiple test cases.

Assertation- To check the result of a test case against the expected result.

Now to open the test suite wizard, Right-click on new project and select New–> From Gallery–> General–> Unit Tests --> ADF Business Components Test Suite



Click on the OK button and configure the test suite. You can see that here I have selected the Model project and DeptAm application module to test. You need to select Configuration for database connection too and here I have selected DeptAMLocal.



Click on the Next button and see that this wizard will generate a Test Suite class and a Test Fixture class. This wizard will also generate separate unit test classes for each view object in the application.



Now click on Finish button and you can under new project all files are created.

DeptAmFixture.java- Test Fixture Class

AllDeptAMTests.java- Test Suite Class

DepartmentsVO1VOTest.java- Unit Test Class for Departments ViewObject



Now open DepartmentsVO1VOTest.java class and look at the default test case that checks that the Department View Object should not be null.

You can see here @Test annotation, this indicates that this java method is a unit test and after performing test assert is used to verify the test result.

  1. @Test
  2. public void testAccess() {
  3. ViewObject view = fixture1.getApplicationModule().findViewObject("DepartmentsVO1");
  4. assertNotNull(view);
  5. }
  6. @Before
  7. public void setUp() {
  8. }
  9. @After
  10. public void tearDown() {
  11. }

To check this default test case, Right-click on the test suite class and select run. You can see that the unit test execute successfully.



The next step is to create some of the own unit tests, I have created this unit test that checks that the Department Id should not be null in a newly created row.

  1. @Test
  2. public void checkDeptIdNotNull() {
  3. ViewObject deptVo = fixture1.getApplicationModule().findViewObject("DepartmentsVO1");
  4. Row newRow = deptVo.createRow();
  5. newRow.setAttribute("DepartmentId", 222);
  6. newRow.setAttribute("DepartmentName", "Testing");
  7. assertNotNull("DepartmentId should not be null", newRow.getAttribute("DepartmentId"));
  8. }

So in the above code, I have created a new row in Department's view object and set 222 in Department Id. Now run this test case.



You can see here that the test is passed successfully because Department Id is not null, That's great. Now comment this line in the code

//newRow.setAttribute("DepartmentId", 222);

and run the test again



See that test is failed with AssertionError as Department Id is null this time. This is how we can write our own unit tests to check.

Here I am writing one more test case to check whether the department is in the database or not. I am passing 1990 as department id that is not in the database.

  1. @Test
  2. public void findDepartment() {
  3. ViewObject deptVo = fixture1.getApplicationModule().findViewObject("DepartmentsVO1");
  4. int deptId = 1990;
  5. Row row[] = deptVo.findByKey(new Key(new Object[] { deptId }), 1);
  6. Integer count = row.length;
  7. //assertTrue fails when second parameter evaluates to "false"
  8. assertTrue("Department Not Found", count.compareTo(0) == 1);
  9. }

Let's see the result



This is how we configure and use JUnit in the Oracle ADF Application for Unit Testing.

Cheers 🙂 Happy Learning

Wednesday 13 December 2017

Use ViewObject Query Mode for In-Memory Sorting of data in Oracle ADF


Hello All

Previously I have posted about In-Memory filtering of ViewObject by changing ViewCriteria's query execution mode, Now this post is about In-Memory sorting of records in viewObject. By default sorting and filtering in viewObject works on the rows retrieved from DB

We can change ViewObject Query mode as per our requirement, There are 3 different SQL query mode


Monday 13 November 2017

ADF Basics: Add the row at the end of ViewObject's current RowSet in ADF


This post is about adding a row at the end of current rowset of viewObject without using table or any other UI components binding


Here I have a Department ViewObject (HR Schema), dropped as a table on page and a button to add new row, this button calls a method from model using binding layer 

Wednesday 13 September 2017

ADF Basics: Filter ViewObject data using getFilteredRows and RowQualifier


Sometimes we need to get filtered data from ViewObject using one or multiple conditions,
Though this is the very basic of framework yet new developers find it confusing.

There are two ways of filtering ViewObject

 1. In this we apply WHERE clause on ViewObject and it affects resultSet data, Suppose we have Department ViewObject and we want to see data of DepartmentId 4 on page after filtering, for this viewCritera, bind variables comes in action
ADF Basics: Apply and Change WHERE Clause of ViewObject at runtime programmatically

2. In this user want to get filtered data (Rows) in code only without any effect on ViewObject resultSet (page data), Here I am discussing this point

We can get filtered data from view object using two methods-

Friday 12 May 2017

Understanding Nested Application Modules in Oracle ADF


Application Module acts as a container for view Object and view Link business components that are used in a specific task. It provides data model and data control to show required information and perform action for the client
An application module represents a single transaction and owns one database connection that's why commit and rollback works for all view Objects inside an application module

Thursday 4 May 2017

Implement contains/endswith behavior in model based autoSuggest Lov (Input list and combo box)


Hello All

Hope Everyone knows about list of values and autoSuggest beahvior of ADF Framework,
For those who are new to framework can look at this post
ADF Basics : Implementing auto suggest behavior in ADF Faces lov (list of values)

Tuesday 11 April 2017

Oracle ADF Best Practices, Mistakes and Worst Practices


In this post I am putting some practices and that we should follow while using Oracle Application Development Framework for development


Monday 20 March 2017

ADF Basics: Tip for not showing record in dependent lov


Hello All

Recently I have seen a question on OTN forum - Question on cascading LOV

It was about cascading lovs in ADF
Suppose we have 2 dependent LOVs and requirement is that 2nd lov should not show any data until first one is selected , this is very simple and common use case but for beginners it's a tedious task

So I thought to write it here to help others

Tuesday 17 January 2017

ADF Basics: Duplicate Record Validation Using Custom Java Method


Hello All

Recently I have posted about duplicate record validation using model level business rules (Unique Key Validation) but sometimes we need to check some more conditions or we have some other logic that should be checked before validating the input then in that case we can write custom java method in model (Application Module Impl class) and call it in bean validator using binding layer

Thursday 12 January 2017

ADF Basics: Duplicate Record Validation Using Model Level Business Rules


Hello All

Hope you all are doing well :)

When we are creating any data entry form , at that time preventing duplicate entries for some of attributes is very basic validation requirement .

Suppose We are creating a form to make new Departments entry and  there should not be two departments with same name so for this type of validation we need not to write single line of code in Oracle ADF as there are predefined business rules for basic validation

Saturday 30 July 2016

ADF Basics: Populate simple programmatic View Object using POJO


Hello All

I hope you all know that we have 4 type of viewObjects in ADF, Here we'll discuss about a simple programmatic viewObject
  • Entity Object Based
  • SQL Query Based
  • Static List Based
  • Programmatic ViewObject
Programmatic ViewObject can be created by overriding appropriate methods in ViewObject's Impl class to retireve data from REF CURSOR, Array or any Java file
Here in this post I am using an ArrayList (POJO based) to populate viewObject records so for that I'll override some methods of ViewObject Impl class

Wednesday 30 December 2015

Create REST Web Service with Application Module declaratively in ADF 12.2.1

REST stands for Representational State Transfer, REST is an architectural style not a protocol as SOAP that's why it can use any other protocol like SOAP, HTTP etc.
REST requires less bandwidth and resources (lighter) than SOAP

New ADF 12.2.1 supports creating RESTful web services directly from Application Module, In previous versions we have to do everything manually
See- Create RESTful services on top of ADF Business Components

Tuesday 22 December 2015

Create SOAP Web Service with Application Module quickly in ADF 12.2.1


SOAP stands for Simple Object Access Protocol, a protocol to exchange information in XML format between two applications over HTTP. This protocol is used to create ,access and consume web services.

SOA (Service Oriented Architecture) focuses on re-usability and exposing application module as web service makes it's methods and objects accessible from any device , any platform and these methods and objects can be further used by any other application

Saturday 4 July 2015

ADF Basics: How to invoke model layer methods from managed bean (Best Practice to write business logic in ADF)

Again a post about ADF Basics for those who are starting with ADF
This topic is posted multiple times and one of the most asked question on OTN

How to access AM method in bean ?
How to pass parameters to model from managed bean (viewController) ?
How to pass taskFlow parameter to model ?

Or sometimes I have to tell user that you should not access ApplicationModule or not update model from managed bean and then i post a link about this
I often post a link of Frank's blog
Best practice invoking business services methods from JSF beans
It is well explained but still user not able to do because he/she doesn't know about clientInterface, pageDef etc

So i thought to write a step by step implementation of this and if you want to know why it is best to call method through binding layer ?
Then please refer Frank's blog :)

What i am going to explain is How to call a method defined in ApplicationModule Impl class in managed bean ?
So for this first i need to define a method in ApplicationModule Impl class




Here i am using Departments table of HR Schema and i have created a method to create new row in Departments viewObject
See implementation part -

  • To create AMImpl class--> Open ApplicationModule in editor--> Goto Java tab--> Click on edit (pencil) icon and check the checkbox to generate class



  • Now write your logic and create method here so i have created a method to create department record and this method takes a parameter i;e DepartmentId

  •     /**
         *Custom Method to create row in departments viewObject
         */
        public void createDepartmentRecord(Integer deptId) {
            ViewObject deptVo = this.getDepartmentsVO1();
            Row newRow=deptVo.createRow();
            newRow.setAttribute("DepartmentId", deptId);
            deptVo.insertRow(newRow);
        }
    

  • Next step is to add this method to client interface so that we can access this , Again open AM in editor -->Go to Java tab--> Click on edit icon of clientInterface--> Shuttle method to selected side


  • Now to add this method in pageDef , Open page in editor--> Click on Bindings tab (bottom of editor)--> Click on green plus icon of bindings section--> Select methodAction and click on ok



  • Now select method name here and click ok


    Now you can see this method is added in pageDef


  • Now time to call this method in managed bean so for that added a button in page and created actionListener in bean . See the code 

  •     /**Method to get Binding Container of page
         * @return
         */
        public BindingContainer getBindings(){
            return BindingContext.getCurrent().getCurrentBindingsEntry();
        }
    
        /**Calling method defined in AMImpl class to create new Department
         * @param actionEvent
         */
        public void callAMMethodToCreateDepartmentAction(ActionEvent actionEvent) {
            //Get OperationBinding of method
            OperationBinding ob=getBindings().getOperationBinding("createDepartmentRecord");
            //Passing parameter to method -Get parameter map and use paramater name as key
            ob.getParamsMap().put("deptId", 9999);
            //Execute this method
            ob.execute();
            //Check for errors
            if(ob.getErrors().isEmpty()){
                // Successfully Executed
            }
        }
    

  • Now run application and check , is it working ? ;)

On click a new row is inserted in table with DepartmentId 9999


All done :)
In same way you can call method defined in any model implementation class, remember don't access ApplicationModule or viewObject directly , make use binding layer
and again why it is best practice ?? to know this read Frank's blog :)

Cheers :) Happy Learning 

Monday 5 January 2015

ADF Basics: Delete child records on delete of parent record, Overriding remove() in EntityObject class

This post is about one basic question of Master-Detail relation between business components
How to delete all child records on delete of parent record ?
So answer is quite simple , see the steps how to achieve this?

  • Create a Fusion Web Application and prepare model project using Departments and Employees table of HRSchema.
    you can see multiple associations and viewLinks are created automatically due to foreign key relation in database


  • Here Departments is parent table and Employees is child, so there is an association between both entity objects , open this association and goto Association Properties . Now you can see source and destination accessor name that are created in both entity objects




  • Next step is to create EntityObject java class. To do this open Departments entity object -- go to java section-- click on edit icon and check the box to create class and required methods
    See Accessors and Remove Method will be created in this class


  • Open DepartmentsEOImpl class and check there is a method that returns RowIterator of Employees (this is Accessor)

  •     /**
         * @return the associated entity oracle.jbo.RowIterator.
         */
        public RowIterator getEmployeesEO1() {
            return (RowIterator)getAttributeInternal(EMPLOYEESEO1);
        }
    

  • Now locate remove method in EOImpl, this method is called every time when delete operation for Departments is executed so add this code to remove(); method

  •     /**
         * Add entity remove logic in this method.
         */
        public void remove() {
            //Get all Employees of currenlty selected Department
            RowIterator employees = getEmployeesEO1();
            while (employees.hasNext()) {
                //Delete all Employees
                employees.next().remove();
            }
            //Delete Department itself after deleting all Employees associated with it
            super.remove();
        }
    


This is how we can make use EntityObject class and Association accessors, in the same way other operation can be performed as updating all child rows, sum of a column of child records etc
Thnaks , Happy Learning :)

Wednesday 10 September 2014

Dynamic (parameterize) model level validation using message token -Oracle ADF

Hello all
This post falls under ADF Basics category (about a little trick in model layer) but about a common development requirement
How can we create dynamic ADF BC validation ? means it takes a parameter at run time and append it to validation message

Read previous post on model level validation-
Conditional Execution of Model (EO) level Validation- Oracle ADF
ViewObject Validation rules for transient attributes (Model level validation in ADF)

In this post I am using Departments table of oracle HR Schema



  • First step is same , prepare model (EO,VO and AM) using Departments table



  • Creating a business rule that DepartmentName can not be duplicate, for this created a alternate key in EntityObject 



  • Nnow creating unique key business rule for this alternate key and message that appears on validation failure (this is how we apply EO level validations)




  • Run AM and check in BC4J tester, create a new row and on entering duplicate DepartmentName this validation message appears -"Duplicate Department Name"


  • now my requirement is this message should be like - Duplicate Department Name <Administration> , so for this i have to pass parameter in message that shows entered DepartmentName on run-time. ADF provides built in feature to pass tokens in message and on run time it is replace with groovy expression value

  •  On running see desired output



  • to pass more than one parameter just add another token and set groovy for it, see the screens
 Output-


Thanks - Happy Learning :)

Tuesday 20 May 2014

Blocking row navigation in af:table , synchronize row selection with model in case of validation failure- Oracle ADF

In ADF we often work on editable af:table and when we use af:table to insert ,update or delete data, it is normal to use some validation
but problem is when some validation failure occurs on page (in af:table) ,still we can select another row and it shows as currently selected Row
this is a bit confusing for user as Row Selection of af:table is not synchronized with model or binding layer

See Problem- 
  • I have an editable table on page


  • Added a validation to check negative value in field of LocationId, now navigate to another row


  • See selected focus is on Academic, but problem is when there is validation failure, why it is showing other row as selected ? 



  • If you check in ViewObject , you will find that row with DepartmentName Human Resource is current row

ADF framework provides a property in af:table to control navigation in af:table when there is some error or validation failure- blockRowNavigationOnError
See in oracle docs about this proprty-

Valid Values: always, never, auto


Whether we want to block row navigation in case of validation failure.
This is when you select a row and do some editing inside the table or in a related form, and this editing causes some validation failures. At this time, if you click on a different row in table, we want to block you from moving to the new row.
possible values are: always, never and auto. default value is auto.

  • always means we block the row navigation
  • never means we don't block and let the row navigation happen
  • auto means the framework will make the decision



by default in af:tabel it's value is <auto>


Change it to <always> and now see behavior on page


 now if you try to select another row, it is not get selected and selected focus is on row with validation

Sample ADF Application-Download
Cheers - Happy Learning :-)

Thursday 17 April 2014

ViewObject Validation rules for transient attributes (Model level validation in ADF)

Hello All,
this post is about model level validation for transient attributes, often we need to apply some common types of validation on transient attributes (as for negative value, for email, for phone number)
in ADF ViewObject there is a editor for validation rules for transient attributes, so now see how to use that editor and rules


  • Create a fusion web application and prepare model layer using Departments table of HR schema


  • Then create a transient attribute in viewObject and you can see that Validation Rules tab appears only in case of transient attribute



  • Now click on add icon to add new validation rule for attribute, you can see there are multiple types for that validation rule 





  • In this post i have used Compare and Regular Expression rules, suppose i have to check that value of transient attribute must not be 100 , so for that rule will be like this, and write a proper message for failure handling 



  • Now run your BC4J tester and check , a window with error message appears there in case of failure


  • You can also check this validation on your page, some more- i have added one more transient field for Email Address and applied a regular expression to validate this field (ADF by default provides regular expression for Email and Phone Number pattern for others you can use your own pattern)


  • After model level configurations , i have dropped Departments ViewObject on page as ADF form, here you can see both validation are working 




Cheers :-) Happy Learning