#ExpectedException in grails unit tests - unit-testing

Anyone used this annotation in grails unit tests?
Didnt seem to work for me.
Thanks.
D
Update: the last line of my test below does throw the expected exception. However the test fails (Stack trace too big for here...). I'm using grails 1.2 and running the test in eclipse's junit runner. Maybe grails is using an earlier version of junit than 4?
/**
* Get the EC by a manager of a different company. Should throw exception
*/
#ExpectedException(ServiceAuthorizationException.class)
void testGetEcByNonOwnerManagerOfDifferentCompany() {
mockDomain(ExpenseClaim , [new ExpenseClaim(id:"1",narrative:"marksClaim", employee:userMark, company:dereksCompany)])
def authControl = mockFor(AuthenticateService)
authControl.demand.userDomain(1..1) {-> otherUserMgr }
authControl.demand.ifAllGranted(1..1) {String arg1 -> return "ROLE_COMPANYMANAGER".equals(arg1) } //returns true
def testService = new ExpenseClaimService()
testService.authenticateService = authControl.createMock()
def thrown = false
testService.getExpenseClaim("1")
}

Only JUnit 3 is currently supported, so use shouldFail() instead:
void testGetEcByNonOwnerManagerOfDifferentCompany() {
shouldFail(ServiceAuthorizationException) {
mockDomain(ExpenseClaim , [new ExpenseClaim(id:"1",
narrative:"marksClaim", employee:userMark,
company:dereksCompany)])
def authControl = mockFor(AuthenticateService)
authControl.demand.userDomain(1..1) {-> otherUserMgr }
authControl.demand.ifAllGranted(1..1) {String arg1 ->
"ROLE_COMPANYMANAGER".equals(arg1) } //returns true
def testService = new ExpenseClaimService()
testService.authenticateService = authControl.createMock()
testService.getExpenseClaim("1")
}
}
shouldFail() is actually more convenient since you can use it more than once per test, and it returns the exception message so you can assert based on the message as well as the exception.

Related

IllegalArgumentException while running contract unit test in Kotlin (Corda)

When I try to run my Junit tests (Wrote in Kotlin) I get the following exception :
java.lang.IllegalArgumentException: Attempted to find dependent attachment for class javax/xml/bind/DatatypeConverter, but could not find a suitable candidate.
I tried to comment/decomment some lines in following code, it seems that the exception occurs when I call command()
class IRIssueTests {
class DummyCommand : TypeOnlyCommandData()
private val ledgerServices = MockServices(listOf("com.my.package.name"))
private val ALICE = TestIdentity(CordaX500Name(organisation = "Alice", locality = "TestLand", country = "US"))
#Test
fun mustIncludeIssueCommand() {
val ir = IRState(
UniqueIdentifier(),
mutableListOf(ALICE.party)
)
ledgerServices.ledger {
transaction {
output(IRContract.ID, ir)
command(listOf(ALICE.publicKey), DummyCommand())
fails()
}
transaction {
output(IRContract.ID, ir)
command(listOf(ALICE.publicKey), IRContract.Commands.Issue())
verifies()
}
}
}
}
I would like to understand why I'm getting this exception and how to resolve it to make my test passing
Kotlin tests must be run with JDK8.
Change configuration of JDK8 in your project before running tests.
This will avoid this exception

How to test a grail service that has resultTransformer within withCriteria(Spock).?

In the below class, I just need RevShareFormula.withCriteria to return a result,
but getting the exception in resultTransformer() method.
Can anyone tell me how to Mock the below method so that i get some result from withCriteria
Here is the class:
class PartnerFinancialService {
def getPartnerPayeeRevenuShareDetails(long partnerPayeeId, def contextTypeCode) {
def partnerPayeesRevShareFormula = RevShareFormula.withCriteria {
resultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
createAlias('partnerRevShareConfig', 'partnerRevShareConfig')
createAlias('pricingModel', 'pricingModel')
createAlias('partnerRevShareConfig.revshareCategory', 'revshareCategory')
and {
eq("revshareCategory.payeeProfileId", partnerPayeeId)
eq("revshareCategory.referenceContextTypeCode", contextTypeCode)
isNull("partnerRevShareConfig.revshareValidToDate")
}
projections {
property("id", "formulaId")
property("pricingModel.id", "pricingModelId")
property("pricingModel.pricingName", "pricingName")
property("pricingModel.pricingType", "pricingType")
..
..
}
}
}
Here is the test class
#TestFor(PartnerFinancialService)
#Mock(RevShareFormula)
class PartnerFinancialServiceSpec extends Specification {
void "test getPartnerPayeeRevShareDetails"() {
def partnerPayeeRevShare = new PartnerRevShareConfig()
partnerPayeeRevShare.id = 1
def revShareModel = new PricingModel();
revShareModel.id = 1
def partnerPayeeRevShareFormula = new RevShareFormula();
partnerPayeeRevShareFormula.id=5
partnerPayeeRevShareFormula.pricingModel = revShareModel
partnerPayeeRevShareFormula.partnerRevShareConfig = partnerPayeeRevShare
partnerPayeeRevShareFormula.revshareFormula = "revshare*10"
partnerPayeeRevShareFormula.revshareTierHighValue = 0
partnerPayeeRevShareFormula.revshareTierLowValue= 0
RevShareFormula.metaClass.static.withCriteria = {partnerPayeeRevShareFormula}
when:
def result = service.getPartnerPayeeRevenuShareDetails(1,"PKG")
then:
//assert result.pricingModel.id == 1
println "Succesfully Fetched from DB"
}
}
Getting the following exception.
<testcase classname="com.orbitz.dat.partners.PartnerFinancialServiceSpec" name="test getPartnerPayeeRevShareDetails" time="0.039">
<error message="No signature of method: com.orbitz.dat.partners.PartnerFinancialService.resultTransformer() is applicable for argument types: (org.hibernate.transform.AliasToEntityMapResultTransformer) values: [org.hibernate.transform.AliasToEntityMapResultTransformer#3632aa4]" type="groovy.lang.MissingMethodException">groovy.lang.MissingMethodException: No signature of method: com.orbitz.dat.partners.PartnerFinancialService.resultTransformer() is applicable for argument types: (org.hibernate.transform.AliasToEntityMapResultTransformer) values: [org.hibernate.transform.AliasToEntityMapResultTransformer#3632aa4]
at com.orbitz.dat.partners.PartnerFinancialService.$tt__getPartnerPayeeRevenuShareDetails_closure24(PartnerFinancialService.groovy:39)
at grails.gorm.CriteriaBuilder.invokeClosureNode(CriteriaBuilder.java:1093)
at grails.gorm.CriteriaBuilder.invokeMethod(CriteriaBuilder.java:314)
at org.grails.datastore.gorm.GormStaticApi.withCriteria_closure11(GormStaticApi.groovy:304)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:302)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:37)
at org.grails.datastore.gorm.GormStaticApi.withCriteria(GormStaticApi.groovy:303)
at com.orbitz.dat.partners.PartnerFinancialService.$tt__getPartnerPayeeRevenuShareDetails(PartnerFinancialService.groovy:38)
at com.orbitz.dat.partners.PartnerFinancialServiceSpec.test getPartnerPayeeRevShareDetails(PartnerFinancialServiceSpec.groovy:71)
Use an integration test. Never test ORM code with unit tests. I know it's slower and the experience is less enjoyable, but you are fooling yourself if you think that you are actually testing something related to database queries with this test. You are testing the testing framework of grails (the in-memory GORM implementation)

How to mock Shiro accessControl() method in grails unit test case

I am using shiro security in my grail application.
Grails version : 2.2.1
shiro : 1.2.0
I have a problem in writing grails unit test case for the controller with filter enabled. When the test case run without filters then it is working fine, if it runs withFilters then it is failing for accessControl() method not found in the controller. I dont know how to make Shiro's api to be visible while running the test case.I referred shiro unit test case link http://shiro.apache.org/testing.html but I couldn't get any info regarding accessControl().I have given sample code how my classes and test case looks like
MyController.groovy
def create() {
// getting request parameters and validation
String emailId = params.emailId
def ret = myService.createUser(emailId)
return ret
}
MyControllerFilters.groovy
def filters = {
loginCheck(controller: 'user') {
before = {
//do some business checks
// Access control by convention.
accessControl() // This is a dynamic method injected by ShiroGrailsPlugin to FilterConfig, but this is not visible during the test case.
}
}
MyControllerTests.groovy
#TestFor(MyController)
#Mock(MyControllerFilters)
class MyControllerTests {
#Before
void setup() {
// initializing some variables
}
void testCreateUserWithFilter() {
request.accessAllowed = true
withFilters(action:"create") {
controller.create()
}
assert response.message == "success"
}
}
Try to use:
ControllerOrService.metaClass.method = {
return "" //what you need to be returned
}
Add parameters to closure if method take parameters:
ControllerOrService.metaClass.method = { def a, def b ->
return a + b
}
Don't forget to use full name of method when you mock them in that way.

Grails metaclass modification not reliable within unit tests

In a grails 2 project I'm using groovy's metaclass programming to add some methods to my domain classes.
Everything is working fine at runtime and I can run my integration tests fine.
But for unit tests I have some issues.
I have created a test mixin that is in charge of initializing the metaclass programming part.
This mixin is not running reliably:
the methods added to the metaclass are not available, or they are available after a first call, or they are available only after a previous grails test-app unit: command has been called.
This is quite a problem for continuous build.
You should be able to reproduce this issue (at least with grails 2.0.4) by
0) create a new grails projects
1) add a domain object
create-domain-class playground.Data
2) add this class to your src/groovy/playground dir
package playground
import grails.test.mixin.domain.DomainClassUnitTestMixin
import grails.test.mixin.support.GrailsUnitTestMixin
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.commons.GrailsDomainClass
import org.junit.Before
class EnhanceDomainTestMixin {
boolean enhancerMethodCalled = false;
GrailsApplication application
MetaMethod mockDomainMethod
//replace the mockDomain Method from DomainClassUnitTestMixin with this closure
def enhancedMockDomain = { Class cl, List list ->
def enhanced =cl.metaClass.getMetaMethod("isEnhanced")
try {
//run the mockDomain method to have the mocked domain class registered in the grails application
mockDomainMethod.invoke(delegate, cl, list)
}
finally {
//enhance the grails domain with a new method
def domain = application.getDomainClass(cl.name) as GrailsDomainClass
domain.metaClass.isEnhanced = { return true; }
assert domain.newInstance().isEnhanced();
}
}
#Before void runDomainEnhancer() {
enhancerMethodCalled = true;
//GrailsUnitTestMixin.initGrailsApplication() should have already been called. (at least this was not an issue here)
application = GrailsUnitTestMixin.grailsApplication
//pick the mockDomain method
mockDomainMethod = DomainClassUnitTestMixin.metaClass.pickMethod("mockDomain", Class, List)
//if the picked mockDomain has never been enhanced, wrap it.
if(mockDomainMethod != enhancedMockDomain) {
DomainClassUnitTestMixin.metaClass.mockDomain = enhancedMockDomain
}
}
}
3) Add this small utils class (in test/unit/playground)
package playground
class TestSetup {
static Data d1
static void setup() {
d1 = new Data()
assert d1.isEnhanced()
}
}
4) Add these tests into the unit test already created by grails DataTests
package playground
import grails.test.mixin.*
#TestFor(Data)
#TestMixin(EnhanceDomainTestMixin)
class DataTests {
void testIsEnhancedLocal() {
assert enhancerMethodCalled
Data d = new Data()
assert d.isEnhanced()
}
void testIsEnhancedLocalSecondTime() {
assert enhancerMethodCalled
Data d = new Data()
assert d.isEnhanced()
}
void testIsEnhancedGlobalFirstTime() {
assert enhancerMethodCalled
TestSetup.setup()
assert TestSetup.d1 != null
}
void testIsEnhancedGlobalSecondTime() {
assert enhancerMethodCalled
TestSetup.setup()
assert TestSetup.d1 != null
}
}
Now run this command:
grails test-app unit:
you should have something like this output:
| Completed 4 unit tests, 4 failed in 1651ms
| Tests FAILED - view reports in target\test-reports
Now run the this command again (sometime one more is needed):
grails test-app unit: playground.DataTests
testMixin> grails test-app unit: playground.DataTests
| Completed 4 unit tests, 0 failed in 1384ms
| Tests PASSED - view reports in target\test-reports
So does anyone has a clue of why the metaClass modification is not reliable while running unit tests ? And how to workaround this issue ?
I had to use grailsApplication config in my domain class method. I ran into the same problem. Try using Holders.config instead of grailsApplication.config. It worked for me.

Second Use of GrailsApplication Mock in Service Test Fails

I'm unit testing a Grails service and using Mocks to mock out calls to the
GrailsApplication class. I have one test that succeeds but when I try
subsequent tests they fail. I am using demand to mock the isDomainClass
method. I have tried copying and pasting the code from the test that
succeeds to the test method that fails but the second time the same code
runs it fails saying that no more calls to isDomainClass are expected. I'm
suspecting some leakage between the methods but I can't see where it is.
Things I've tried already:
Running the tests from the command line (I'm running the tests under SpringSource Tool Suite version 2.7.0.201105292341-M2.)
Moving the failing test to a different test class (the test that runs first succeeds)
Changing the number range in the demands clause to 1..5 (second test still fails)
Here is the relevant portions of my test case:
package simulation
import grails.test.*
import org.joda.time.*
import org.codehaus.groovy.grails.commons.GrailsApplication
class ObjectSerializationServiceTests extends GrailsUnitTestCase {
def objectSerializationService
protected void setUp() {
super.setUp()
objectSerializationService = new ObjectSerializationService()
}
protected void tearDown() {
super.tearDown()
objectSerializationService = null
}
void testDomainObjectSerialization() {
def otherControl = mockFor(GrailsApplication)
otherControl.demand.isDomainClass(1..1) {true}
otherControl.demand.getDomainClass(1..1) {className ->
assert className == "simulation.TestDomainClass"
TestDomainClass.class
}
objectSerializationService.grailsApplication = otherControl.createMock()
def now = new DateTime()
def testObject = new TestDomainClass([id:57, someOtherData:"Some Other
Data", theTime:now])
def testInstances = [testObject]
mockDomain(TestDomainClass, testInstances)
def serialized = objectSerializationService.serializeObject(testObject)
def deserialized =
objectSerializationService.deserializeObject(serialized)
assert deserialized == testObject
assert serialized.objectType == SerializedObject.ObjectType.DOMAIN
otherControl.verify()
}
void testSerializableSerialization() {
def otherControl = mockFor(GrailsApplication)
otherControl.demand.isDomainClass(1..1) {true}
otherControl.demand.getDomainClass(1..1) {className ->
assert className == "simulation.TestDomainClass"
TestDomainClass.class
}
objectSerializationService.grailsApplication = otherControl.createMock()
def now = new DateTime()
def testObject = new TestDomainClass([id:57, someOtherData:"Some Other
Data", theTime:now])
def testInstances = [testObject]
mockDomain(TestDomainClass, testInstances)
def serialized = objectSerializationService.serializeObject(testObject)
def deserialized =
objectSerializationService.deserializeObject(serialized)
assert deserialized == testObject
assert serialized.objectType == SerializedObject.ObjectType.DOMAIN
otherControl.verify()
}
}
And the output:
Testcase: testDomainObjectSerialization took 0.943 sec
Testcase: testSerializableSerialization took 0.072 sec
FAILED
junit.framework.AssertionFailedError: No more calls to 'isDomainClass'
expected at this point. End of demands.
at grails.test.MockClosureProxy.doBeforeCall(MockClosureProxy.java:66)
at grails.test.AbstractClosureProxy.call(AbstractClosureProxy.java:74)
at
simulation.ObjectSerializationService.serializeObject(ObjectSerializationService.groovy:20)
at simulation.ObjectSerializationService$serializeObject.call(Unknown
Source)
at
simulation.ObjectSerializationServiceTests.testSerializableSerialization(ObjectSerializationServiceTests.groovy:68)
I got a similar error trying to use mockFor on jms Message interface in multiple test cases.
I got around it by creating a custom interface that extends from the interface that needs to be mocked. You would use the custom interface to create the mock.
e.g.
private interface GrailsApplicationTest1 extends GrailsApplication(){}
testOne(){
def control = mockFor(GrailsApplicationTest1)
//...rest of code
}
private interface GrailsApplicationTest2 extends GrailsApplication(){}
testTwo(){
def control = mockFor(GrailsApplicationTest2)
//...rest of code
}
//add more private interfaces for additional test cases..
I'm not exactly sure why but I think the mockFor behaves differently between interfaces and non-interfaces. But that's just a wild guess.