0

I am writing unit test cases for my Service Class. Below is my code in controller:

TuneController

def list = {

}

def listData= {

    playerId="6600AE"
    def tuneInstanceList = new ArrayList<Tune>()


    tuneInstanceList = tuneService.calculateId(String playerId)


    def editResult = [total: tuneInstanceList.size(), items: tuneInstanceList]


    render editResult as JSON;
}

Below is my code in TuneService: The below method is called from listData action. ListData is mentioned in my js file test.js

List<Tune> calculateId(String playerId) {             

   try{
   //read the sql file 
        String playerSql = grailsApplication.mainContext.getResource('classpath:' +         Constants.PLAYER_FILE).inputStream.text 

    def sql = new groovy.sql.Sql(dataSource)                 

    def params = [playerId:playerId] 
    def tuneInstanceList = new ArrayList<Tune>() 

    def results = sql.rows(playerSql, params) 

    tuneInstanceList = results.each { 
        def tune = new Tune() 
        tune.setPlayerId  it.player_id   
        tuneInstanceList.add tune
    }
    return tuneInstanceList

}catch (Exception ex) {
        log.error ex.message, ex
        throw ex
    }
    //finally {
        //sql.close()
    //}
}

PLAYER_FILE.sql has the below data. This file is present in grails-app/sql/PLAYER_FILE.sql

select player_Id from tunes where player_Id=:playerId

Test.js:

Ext.onReady(function(){ 

// create the Data Store 
var ds = new Ext.data.Store({ 
   autoLoad: true, 
   proxy: new Ext.data.HttpProxy({ 
   url: 'http://localhost:8080/music/tune/listData'}), 
   reader: new Ext.data.JsonReader({ 
    results: 'total', 
    root:'items', 
    id:'id' 
   }, 
   [ 
           {name: 'playerId' } 

      ] 
   ) 
}); 

var cm = new Ext.grid.ColumnModel([ 
    {header: "Player Id", width: 120, dataIndex: 'playerId' }, 

]); 
cm.defaultSortable = true; 

// create the grid 
var grid = new Ext.grid.GridPanel({ 
    ds: ds, 
    cm: cm, 
    renderTo:'grid-example', 
    width:540, 
    height:200 
});    });

Below is the test that I wrote for my service class. Here I am getting the missing prperty exception. I believe this is for the line "def sql = new groovy.sql.Sql(dataSource)". This is what is mentioned in the exceptions. Its reg. this sql. Here in my test, I have to mention the datasource or mock the datasource. I am not too sure though.

My test case is below:

void testReturnList() {          
    TuneService tuneService = new TuneService()     
    List tuneList = tuneService.calculateId()  
    assertTrue(tuneList.size()>0)   
} 

groovy.lang.MissingPropertyException: No such property: sql for class: pride.TuneService Possible solutions: log at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:49) at org.codehaus.groovy.runtime.callsite.GetEffectivePogoPropertySite.getProperty(GetEffectivePogoPropertySite.java:86) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:241) at pride.TuneService.calculateId(TuneService.groovy:67) at pride.TuneService$calculateId.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117) at pride.TuneServiceTests.testReturnList(TuneServiceTests.groovy:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at junit.framework.TestCase.runTest(TestCase.java:168) at junit.framework.TestCase.runBare(TestCase.java:134) at junit.framework.TestResult$1.protect(TestResult.java:110) at junit.framework.TestResult.runProtected(TestResult.java:128) at junit.framework.TestResult.run(TestResult.java:113) at junit.framework.TestCase.run(TestCase.java:124) at junit.framework.TestSuite.runTest(TestSuite.java:232) at junit.framework.TestSuite.run(TestSuite.java:227) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

EDITED: Below is the error that I get after commenting sql.close()

java.lang.NullPointerException: Cannot get property 'mainContext' on null object at org.codehaus.groovy.runtime.NullObject.getProperty(NullObject.java:56) at org.codehaus.groovy.runtime.InvokerHelper.getProperty(InvokerHelper.java:156) at org.codehaus.groovy.runtime.callsite.NullCallSite.getProperty (NullCallSite.java:44) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty (AbstractCallSite.java:237) at pride.TuneService.calculateId(TuneService.groovy:37) at pride.TuneService$calculateId.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:117) at pride.TuneServiceTests.testReturnList(TuneServiceTests.groovy:23) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at junit.framework.TestCase.runTest(TestCase.java:168) at junit.framework.TestCase.runBare(TestCase.java:134) at junit.framework.TestResult$1.protect(TestResult.java:110) at junit.framework.TestResult.runProtected(TestResult.java:128) at junit.framework.TestResult.run(TestResult.java:113) at junit.framework.TestCase.run(TestCase.java:124) at junit.framework.TestSuite.runTest(TestSuite.java:232) at junit.framework.TestSuite.run(TestSuite.java:227) at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

How do I go about writing this test case. Thoughts?

MAlex
  • 1,234
  • 2
  • 16
  • 29
  • For future questions, please take some time to learn the StackOverflow code formatter to make your questions cleaner and easier to read. http://stackoverflow.com/editing-help – Rob Hruska Oct 21 '10 at 13:18
  • why are you using grails and then not using the GORM functionality? Looks like you are groovy sql. – Aaron Saunders Oct 21 '10 at 14:16
  • Yes....You can say that Aaron. These are customized queries used in my project. Its a parrt of a whole lot that I have mentione here – MAlex Oct 21 '10 at 18:27

1 Answers1

0

I don't think you've given us the right code to help you debug this error. If you examine the stack trace more closely, you'll see where the "missing property" is:

at pride.RecoveryService.calculateImpact(RecoveryService.groovy:67)

Have a look at that line. It's likely that you're referring to a property called sql that hasn't been defined for the method/closure/class.

Edit:

After your update, I see at least one problem:

String sql = grailsApplication.mainContext.getResource('classpath:' + Constants.PLAYER_FILE).inputStream.text 
def sql = new groovy.sql.Sql(dataSource)  

You're defining sql twice here as different types. I only point that out because your stack trace seems to be related to that variable.

Can you point out which line is line in TuneService.groovy is line 67?

Rob Hruska
  • 118,520
  • 32
  • 167
  • 192
  • Also, have a look at http://stackoverflow.com/questions/3988788/what-is-a-stack-trace-and-how-can-i-use-it-to-debug-my-application-errors to see how to read that stack trace. – Rob Hruska Oct 21 '10 at 15:05
  • I had a finally block in my code which read sql.close(). That was the line number 67. Do not know why that was giving an error, because it works fine whne i run the app otherwise. And as u said, I changed the sql def dtaht was defined twice. Now when I run it I get another error which corresponds to line 37 which is String sql = grailsApplication.mainContext.getResource('classpath:' + Constants.PLAYER_FILE).inputStream.text Do u think I have written my tests fine? – MAlex Oct 22 '10 at 03:48
  • After your update it looks like `grailsApplication` is null in your code. I'm not sure that `grailsApplication` is available to services, and I'm not entirely sure how to access its information otherwise. – Rob Hruska Oct 22 '10 at 04:25
  • If I run my application with this code, it runs fine and I get the desired output. Do you think it has something to do with mocking?I mean is it that my Unit tests are unable to access the .sql file in grails-app folder? Do u think my unit tests are missing something? – MAlex Oct 22 '10 at 04:41
  • Well, if it's a unit test it's doubtful that `grailsApplication` would be available. `grailsApplication` might be available if you were to write the test as an integration test, though. Unit tests don't get any of the dynamic properties that are normally available at runtime. – Rob Hruska Oct 22 '10 at 11:47
  • Thanks Rob. Is there any way grailsApplication can be kept available in Unit Tests? – MAlex Oct 25 '10 at 09:52
  • Well, it wouldn't really make sense. You'd have to mock it out in an unit test. If you need it to exist for your test, you should use an integration test instead, since that's what they're for (providing the application context). – Rob Hruska Oct 25 '10 at 11:59
  • Thanks Rob for your inputs. Integration Test seems to be the right way out. I have written the Integration Test and since its a different code , I have put it as a separate question. "Integration Test with JSON output" is the subject Link: http://stackoverflow.com/questions/4020880/integration-test-with-json-output – MAlex Oct 26 '10 at 05:47