Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Testing without GWTTestCase

    Hi,

    As the latest trends show, testing GWT applications without GWTTestCase is much faster. More important is ability to use great Java mocking libraries, e.g. EasyMock and MockitoNow. If SmartGWT is in use, testing without GWTTestCase is not possible, due to the fact that JSNI method are invoked from constructors on many places.

    How big would be the effort to ensure having default constructors on at least data classes (ListGridRecord, Record...) that do not call JSNI methods? Provided widgets are less problematic, thanks to the good design - they implement always a set of interfaces that could be mocked up, but these interfaces expect or deliver instances of dataclasses that cannot be currently mocked up.

    Best,

    Predrag

    #2
    C'mon guys, no replies? I just fell flat on my face, having rewritten my app to use the MVP pattern und implemented some tests using EasyMock only to discover that SmartGWT doesn't play together at all. Is this in the works or do I need to look for something else?
    Cheers, Thomas

    Comment


      #3
      I'm also in the same boat. Any updates on this?

      Comment


        #4
        For our project, our presenter needed to call DataBoundComponent.fetchData(Criteria). As you know, Criteria can't be created during testing so we used a workaround... We substituted the Criteria with a Map and then created the Criteria in the new fetchData(Map) method. That way, the Criteria gets constructed elsewhere (which means you can mock whatever is constructing it) and the presenter being tested didn't need to construct Criteria objects. Hope that helps!

        Here's an idea of what it looks like:
        Code:
        // In production code
        interface CanFetchData {
            void fetchData(Map<String,String> map);
        }
        
        class MyListGrid extends ListGrid implements CanFetchData {
            ....
            public void fetchData(Map<String,String> map) {
                Criteria criteria = new Criteria();
                // convert map to criteria
                for (Entry<String,String> entry : map.entrySet()) {
                     criteria.addCriteria(entry.getKey(), entry.getValue());
                }
                super.fetchData(criteria);
            }
            ....
        }
        
        class MyPresenter ... {
        
            ....
        
            Display {
                CanFetchData getFetcher();
            }
        
            public void onRevealDisplay() {
                Map<String,String> map = new HashMap<String,String>();
                display.getFetcher().fetchData(map);
            }
        }
        
        // Test code
        void myTest() {
            CanFetchData mockCanFetchData = createMock(CanFetchData.class);
            // mock never creates Criteria
        }

        Comment


          #5
          I can mock SmartGWT classes like Record or Record ClickEvent when I mock them with Powermock (which is a Easymock extension). http://code.google.com/p/powermock/

          There is a possiblity to suppress static initalizers with Powermock for example.

          Bye Henry
          Last edited by thalles; 17 Jan 2011, 01:32.

          Comment


            #6
            Originally posted by thalles
            I can mock SmartGWT classes like Record oder Record ClickEvent when I mock them with Powermock (which is a Easymock extension). http://code.google.com/p/powermock/

            There is a possiblity to suppress static initalizers with Powermock for example.

            Bye Henry
            Could you please provide an example how you mock up Record ?

            Cheers,

            Predrag

            Comment


              #7
              Hi there,

              here is an example where I mock com.smartgwt.client.data.Record and com.smartgwt.client.widgets.grid.events.RecordClickEvent.

              First you need this in the beginning of your test class (I use the latest version of Powermock and Easymock 3.0 in a JUNIT 4 test):

              Code:
              @RunWith(PowerMockRunner.class)
              //used to suppress static blocks in JsObject and DataClass which use native JavaScript methods
              @SuppressStaticInitializationFor({"com.smartgwt.client.core.JsObject","com.smartgwt.client.core.DataClass"})
              public class BaseMapPresenterJRETest extends MapGeneralJRETest {
              In your actual test method you can mock above mentioned classes like this:

              Code:
              RecordClickEvent event = PowerMock.createMock(RecordClickEvent.class);
              Record record = PowerMock.createMock(Record.class);
              expect(event.getRecord()).andReturn(record).anyTimes();
              expect(event.getRecordNum()).andReturn(0).anyTimes();
              expect(record.getAttribute("visibility")).andReturn("false");
              expect(record.getAttribute("name")).andReturn("testName");
              record.setAttribute("visibility", true);
              replay(record);
              replay(event);
              You then execute your method to test and verify the test objects:

              Code:
              presenter.handleRecordClickEvent(event);
              verify(event);
              verify(record);
              Hope this helps.

              Best regards,
              Henry
              Last edited by thalles; 17 Jan 2011, 01:50.

              Comment


                #8
                Originally posted by thalles
                Hi there,

                here is an example where I mock com.smartgwt.client.data.Record and com.smartgwt.client.widgets.grid.events.RecordClickEvent.
                Thanks a lot!

                Comment


                  #9
                  Hi Henry,
                  Can you please let me know if you are able to supress the staic block on widget. Like Canvas which extends BaseWidget (which has a static block init())

                  Thanks
                  San
                  Originally posted by thalles
                  Hi there,

                  here is an example where I mock com.smartgwt.client.data.Record and com.smartgwt.client.widgets.grid.events.RecordClickEvent.

                  First you need this in the beginning of your test class (I use the latest version of Powermock and Easymock 3.0 in a JUNIT 4 test):

                  Code:
                  @RunWith(PowerMockRunner.class)
                  //used to suppress static blocks in JsObject and DataClass which use native JavaScript methods
                  @SuppressStaticInitializationFor({"com.smartgwt.client.core.JsObject","com.smartgwt.client.core.DataClass"})
                  public class BaseMapPresenterJRETest extends MapGeneralJRETest {
                  In your actual test method you can mock above mentioned classes like this:

                  Code:
                  RecordClickEvent event = PowerMock.createMock(RecordClickEvent.class);
                  Record record = PowerMock.createMock(Record.class);
                  expect(event.getRecord()).andReturn(record).anyTimes();
                  expect(event.getRecordNum()).andReturn(0).anyTimes();
                  expect(record.getAttribute("visibility")).andReturn("false");
                  expect(record.getAttribute("name")).andReturn("testName");
                  record.setAttribute("visibility", true);
                  replay(record);
                  replay(event);
                  You then execute your method to test and verify the test objects:

                  Code:
                  presenter.handleRecordClickEvent(event);
                  verify(event);
                  verify(record);
                  Hope this helps.

                  Best regards,
                  Henry

                  Comment


                    #10
                    You definately can, see my post above.

                    Refer to the Powermock Homepage for further details.

                    Best regards,
                    Henry

                    Comment


                      #11
                      Originally posted by sandeepm
                      Hi Henry,
                      Can you please let me know if you are able to supress the staic block on widget. Like Canvas which extends BaseWidget (which has a static block init())

                      Thanks
                      San

                      Got it working using below powermock supress annotation:

                      @SuppressStaticInitializationFor({"com.google.gwt.user.client.ui.UIObject","com.smartgwt.client.widgets.BaseWidget"})


                      Cheers
                      Sandeep

                      Comment


                        #12
                        Hey guys,

                        I wanted to mock a ListGrid using PowerMock:
                        Code:
                        ListGrid listGridMock = PowerMock.createMock(ListGrid.class);
                        but this simple line is generating the following exception:
                        Code:
                        Caused by: java.lang.ClassFormatError: Invalid method Code length 74191 in class file com/smartgwt/client/widgets/grid/ListGrid$$EnhancerByCGLIB$$581539a9
                        anyone knows how to solve this?

                        Comment

                        Working...
                        X