Trace:
Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | Next revision Both sides next revision | ||
jvx:code_snippets [2018/02/06 10:30] admin |
jvx:code_snippets [2018/02/06 10:33] admin |
||
---|---|---|---|
Line 1770: | Line 1770: | ||
} | } | ||
}); | }); | ||
+ | </file> | ||
+ | |||
+ | ==== Test UI with simple JUnit Test ==== | ||
+ | |||
+ | Sometimes you want a JUnit test case for a specific UI feature. If you need an application frame for your test, you could use following implementation: | ||
+ | |||
+ | A simple Test Launcher: | ||
+ | |||
+ | <file java SimpleTestLauncher.java> | ||
+ | /* | ||
+ | * Copyright 2016 SIB Visions GmbH | ||
+ | * | ||
+ | * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
+ | * use this file except in compliance with the License. You may obtain a copy of | ||
+ | * the License at | ||
+ | * | ||
+ | * http://www.apache.org/licenses/LICENSE-2.0 | ||
+ | * | ||
+ | * Unless required by applicable law or agreed to in writing, software | ||
+ | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
+ | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
+ | * License for the specific language governing permissions and limitations under | ||
+ | * the License. | ||
+ | * | ||
+ | * | ||
+ | * History | ||
+ | * | ||
+ | * 11.08.2016 - [JR] - creation | ||
+ | */ | ||
+ | package javax.rad.application; | ||
+ | |||
+ | import javax.rad.ui.IComponent; | ||
+ | import javax.rad.ui.container.IDesktopPanel; | ||
+ | import javax.rad.util.IRunnable; | ||
+ | import javax.swing.JComponent; | ||
+ | import javax.swing.SwingUtilities; | ||
+ | |||
+ | import com.sibvisions.rad.application.Application; | ||
+ | import com.sibvisions.rad.ui.swing.impl.SwingApplication; | ||
+ | |||
+ | /** | ||
+ | * The <code>SimpleTestLauncher</code> starts a {@link SwingApplication} and shows | ||
+ | * a specific content in the application pane. | ||
+ | * | ||
+ | * @author René Jahn | ||
+ | */ | ||
+ | public class SimpleTestLauncher | ||
+ | { | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | // Initialization | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | | ||
+ | /** | ||
+ | * Creates a new instance of <code>SimpleTestLauncher</code>. | ||
+ | * | ||
+ | * @param pComponent the component to show | ||
+ | */ | ||
+ | public SimpleTestLauncher(final IComponent pComponent) | ||
+ | { | ||
+ | final SwingApplication app = new SwingApplication(); | ||
+ | | ||
+ | app.startup(SimpleTestApplication.class.getName(), null, null); | ||
+ | app.setSystemExitOnDispose(false); | ||
+ | app.eventWindowClosed().addListener(new IRunnable() | ||
+ | { | ||
+ | public void run() | ||
+ | { | ||
+ | synchronized (SimpleTestLauncher.this) | ||
+ | { | ||
+ | SimpleTestLauncher.this.notify(); | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | | ||
+ | SwingUtilities.invokeLater(new Runnable() | ||
+ | { | ||
+ | public void run() | ||
+ | { | ||
+ | IDesktopPanel desktop = ((Application)app.getApplication()).getDesktopPane(); | ||
+ | desktop.removeAll(); | ||
+ | desktop.add(pComponent); | ||
+ | | ||
+ | //because test was created before LaF was set! | ||
+ | SwingUtilities.updateComponentTreeUI((JComponent)pComponent.getResource()); | ||
+ | } | ||
+ | }); | ||
+ | | ||
+ | synchronized(this) | ||
+ | { | ||
+ | try | ||
+ | { | ||
+ | wait(); | ||
+ | } | ||
+ | catch (InterruptedException ie) | ||
+ | { | ||
+ | //ignore | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } // SimpleTestLauncher | ||
+ | </file> | ||
+ | |||
+ | This class wrapps application creation, because we need to set the UI component after the application was started! | ||
+ | |||
+ | The second class is our Application: | ||
+ | |||
+ | <file java SimpleTestApplication.java> | ||
+ | /* | ||
+ | * Copyright 2016 SIB Visions GmbH | ||
+ | * | ||
+ | * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
+ | * use this file except in compliance with the License. You may obtain a copy of | ||
+ | * the License at | ||
+ | * | ||
+ | * http://www.apache.org/licenses/LICENSE-2.0 | ||
+ | * | ||
+ | * Unless required by applicable law or agreed to in writing, software | ||
+ | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
+ | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
+ | * License for the specific language governing permissions and limitations under | ||
+ | * the License. | ||
+ | * | ||
+ | * | ||
+ | * History | ||
+ | * | ||
+ | * 11.08.2016 - [JR] - creation | ||
+ | */ | ||
+ | package javax.rad.application; | ||
+ | |||
+ | import javax.rad.application.genui.UILauncher; | ||
+ | import javax.rad.remote.IConnection; | ||
+ | |||
+ | import com.sibvisions.rad.application.Application; | ||
+ | |||
+ | /** | ||
+ | * The <code>SimpleTestApplication</code> is an always connected application | ||
+ | * implementation, for test cases. | ||
+ | * | ||
+ | * @author René Jahn | ||
+ | */ | ||
+ | public class SimpleTestApplication extends Application | ||
+ | { | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | // Initialization | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | |||
+ | /** | ||
+ | * Creates a new instance of <code>SimpleTestApplication</code>. | ||
+ | * | ||
+ | * @param pLauncher the launcher | ||
+ | */ | ||
+ | public SimpleTestApplication(UILauncher pLauncher) | ||
+ | { | ||
+ | super(pLauncher); | ||
+ | } | ||
+ | | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | // Overwritten methods | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | |||
+ | @Override | ||
+ | protected String getApplicationName() | ||
+ | { | ||
+ | return "Test Application"; | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | protected IConnection createConnection() throws Exception | ||
+ | { | ||
+ | return null; | ||
+ | } | ||
+ | | ||
+ | @Override | ||
+ | public void notifyVisible() | ||
+ | { | ||
+ | } | ||
+ | | ||
+ | @Override | ||
+ | protected void afterLogin() | ||
+ | { | ||
+ | } | ||
+ | |||
+ | } // SimpleTestApplication | ||
+ | </file> | ||
+ | |||
+ | The application removes login screen and you can use it without manual tasks. | ||
+ | |||
+ | Finally, our JUnit test case: | ||
+ | |||
+ | <file java TestActivity.java> | ||
+ | /* | ||
+ | * Copyright 2016 SIB Visions GmbH | ||
+ | * | ||
+ | * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
+ | * use this file except in compliance with the License. You may obtain a copy of | ||
+ | * the License at | ||
+ | * | ||
+ | * http://www.apache.org/licenses/LICENSE-2.0 | ||
+ | * | ||
+ | * Unless required by applicable law or agreed to in writing, software | ||
+ | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
+ | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
+ | * License for the specific language governing permissions and limitations under | ||
+ | * the License. | ||
+ | * | ||
+ | * | ||
+ | * History | ||
+ | * | ||
+ | * 11.08.2016 - [JR] - creation | ||
+ | */ | ||
+ | package com.sibvisions.forum; | ||
+ | |||
+ | import javax.rad.application.SimpleTestLauncher; | ||
+ | import javax.rad.genui.UIFactoryManager; | ||
+ | import javax.rad.genui.container.UIPanel; | ||
+ | import javax.rad.genui.layout.UIBorderLayout; | ||
+ | import javax.rad.model.reference.ReferenceDefinition; | ||
+ | |||
+ | import org.junit.BeforeClass; | ||
+ | import org.junit.Test; | ||
+ | |||
+ | import com.sibvisions.apps.components.NavigationTable; | ||
+ | import com.sibvisions.rad.persist.StorageDataBook; | ||
+ | import com.sibvisions.rad.persist.jdbc.DBAccess; | ||
+ | import com.sibvisions.rad.persist.jdbc.DBStorage; | ||
+ | import com.sibvisions.rad.ui.swing.impl.SwingFactory; | ||
+ | |||
+ | public class TestActivity extends UIPanel | ||
+ | { | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | // Initialization | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | |||
+ | /** | ||
+ | * Initializes the unit test. | ||
+ | * | ||
+ | * @throws Exception if initialization fails | ||
+ | */ | ||
+ | @BeforeClass | ||
+ | public static void beforeClass() | ||
+ | { | ||
+ | UIFactoryManager.getFactoryInstance(SwingFactory.class); | ||
+ | } | ||
+ | | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | // Test methods | ||
+ | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | |||
+ | /** | ||
+ | * Tests application start with a custom UI. | ||
+ | * | ||
+ | * @throws Exception if app start fails | ||
+ | */ | ||
+ | @Test | ||
+ | public void testStartApplication() throws Exception | ||
+ | { | ||
+ | DBAccess dba = DBAccess.getDBAccess("jdbc:oracle:thin:@localhost:1521:XE", | ||
+ | "username", "password"); | ||
+ | dba.open(); | ||
+ | | ||
+ | DBStorage dbsContract = new DBStorage(); | ||
+ | dbsContract.setWritebackTable("CONTRACT"); | ||
+ | dbsContract.setDBAccess(dba); | ||
+ | dbsContract.open(); | ||
+ | | ||
+ | DBStorage dbsActivity = new DBStorage(); | ||
+ | dbsActivity.setWritebackTable("ACTIVITY"); | ||
+ | dbsActivity.setDBAccess(dba); | ||
+ | dbsActivity.open(); | ||
+ | | ||
+ | StorageDataBook sdbContract = new StorageDataBook(dbsContract); | ||
+ | sdbContract.open(); | ||
+ | sdbContract.fetchAll(); | ||
+ | sdbContract.setSelectedRow(0); | ||
+ | | ||
+ | StorageDataBook sdbActivity = new StorageDataBook(sdbContract, dbsActivity); | ||
+ | sdbActivity.setMasterReference(new ReferenceDefinition(new String[] {"CONT_ID"}, | ||
+ | sdbContract, | ||
+ | new String[] {"ID"})); | ||
+ | sdbActivity.open(); | ||
+ | | ||
+ | setLayout(new UIBorderLayout()); | ||
+ | | ||
+ | NavigationTable nav = new NavigationTable(); | ||
+ | nav.setDataBook(sdbActivity); | ||
+ | | ||
+ | add(nav); | ||
+ | | ||
+ | new SimpleTestLauncher(this); | ||
+ | } | ||
+ | |||
+ | } // TestActivity | ||
+ | </file> | ||
+ | |||
+ | The result: | ||
+ | |||
+ | {{:jvx:testapp.png?nolink|}} | ||
+ | |||
+ | The database model (Oracle): | ||
+ | |||
+ | {{:jvx:contract_activity.png?nolink|}} | ||
+ | |||
+ | The database objects (Oracle): | ||
+ | |||
+ | <file sql create.sql> | ||
+ | CREATE TABLE CONTRACT | ||
+ | ( | ||
+ | id NUMBER(16) NOT NULL, | ||
+ | title VARCHAR2(1000), | ||
+ | state NUMBER(1) | ||
+ | ) | ||
+ | ; | ||
+ | comment ON COLUMN CONTRACT.id | ||
+ | IS 'PK'; | ||
+ | comment ON COLUMN CONTRACT.title | ||
+ | IS 'Contract title'; | ||
+ | comment ON COLUMN CONTRACT.state | ||
+ | IS 'Contract state'; | ||
+ | ALTER TABLE CONTRACT | ||
+ | ADD constraint CONT_PK PRIMARY KEY (ID); | ||
+ | |||
+ | CREATE TABLE ACTIVITY | ||
+ | ( | ||
+ | id NUMBER(16) NOT NULL, | ||
+ | cont_id NUMBER(16), | ||
+ | name VARCHAR2(1000), | ||
+ | cost NUMBER(10,2), | ||
+ | valid_from DATE, | ||
+ | valid_to DATE, | ||
+ | responsible_user_id NUMBER(16), | ||
+ | validated CHAR(1) DEFAULT 'Y' | ||
+ | ) | ||
+ | ; | ||
+ | comment ON COLUMN ACTIVITY.id | ||
+ | IS 'PK'; | ||
+ | comment ON COLUMN ACTIVITY.cont_id | ||
+ | IS 'Contract FK'; | ||
+ | comment ON COLUMN ACTIVITY.name | ||
+ | IS 'Activity name'; | ||
+ | comment ON COLUMN ACTIVITY.cost | ||
+ | IS 'Activity costs'; | ||
+ | comment ON COLUMN ACTIVITY.valid_from | ||
+ | IS 'Valid from'; | ||
+ | comment ON COLUMN ACTIVITY.valid_to | ||
+ | IS 'Valid to'; | ||
+ | comment ON COLUMN ACTIVITY.responsible_user_id | ||
+ | IS 'Responsible User FK'; | ||
+ | comment ON COLUMN ACTIVITY.validated | ||
+ | IS 'Whether the activity is valid'; | ||
+ | ALTER TABLE ACTIVITY | ||
+ | ADD constraint ACTI_PK PRIMARY KEY (ID); | ||
+ | ALTER TABLE ACTIVITY | ||
+ | ADD constraint ACTI_CONT_FK FOREIGN KEY (CONT_ID) | ||
+ | REFERENCES CONTRACT (ID); | ||
+ | ALTER TABLE ACTIVITY | ||
+ | ADD constraint ACTI_RESP_USER_FK FOREIGN KEY (RESPONSIBLE_USER_ID) | ||
+ | REFERENCES USERS (ID); | ||
+ | |||
+ | |||
+ | CREATE OR REPLACE TRIGGER TR_ACTIVITY_BR_IU | ||
+ | before INSERT OR UPDATE ON activity | ||
+ | FOR each row | ||
+ | begin | ||
+ | |||
+ | IF (:new.validated = 'N') then | ||
+ | | ||
+ | IF (:new.valid_from IS NULL) then | ||
+ | raise_application_error(-20000, 'Valid from can''t be null!'); | ||
+ | end IF; | ||
+ | | ||
+ | end IF; | ||
+ | | ||
+ | end TR_ACTIVITY_BR_IU; | ||
+ | / | ||
+ | |||
+ | CREATE OR REPLACE TRIGGER TR_CONTRACT_BR_IU | ||
+ | before INSERT OR UPDATE ON contract | ||
+ | FOR each row | ||
+ | begin | ||
+ | |||
+ | IF (:new.state = 4) then | ||
+ | | ||
+ | UPDATE activity | ||
+ | SET validated = 'N' | ||
+ | WHERE cont_id = id | ||
+ | AND validated = 'Y'; | ||
+ | |||
+ | end IF; | ||
+ | | ||
+ | end TR_CONTRACT_BR_IU; | ||
+ | / | ||
+ | |||
+ | |||
+ | ALTER TABLE CONTRACT disable ALL triggers; | ||
+ | ALTER TABLE ACTIVITY disable ALL triggers; | ||
+ | ALTER TABLE ACTIVITY disable constraint ACTI_CONT_FK; | ||
+ | ALTER TABLE ACTIVITY disable constraint ACTI_RESP_USER_FK; | ||
+ | INSERT INTO CONTRACT (id, title, state) | ||
+ | VALUES (1, 'Air', 1); | ||
+ | commit; | ||
+ | INSERT INTO ACTIVITY (id, cont_id, name, cost, valid_from, valid_to, responsible_user_id, validated) | ||
+ | VALUES (1, 1, 'Part 1', .2, NULL, NULL, NULL, 'Y'); | ||
+ | commit; | ||
+ | ALTER TABLE ACTIVITY enable constraint ACTI_CONT_FK; | ||
+ | ALTER TABLE ACTIVITY enable constraint ACTI_RESP_USER_FK; | ||
+ | ALTER TABLE CONTRACT enable ALL triggers; | ||
+ | ALTER TABLE ACTIVITY enable ALL triggers; | ||
</file> | </file> |