I am trying to test the throwing of an exception in my unit test. I tried to metaclass the delete method, but it doesn’t want to stick. Can you tell from the code what I’m doing wrong?
Unit Test code:
@TestFor(ProductController)
@TestMixin(DomainClassUnitTestMixin)
class ProductControllerTests {
void testDeleteWithException() {
mockDomain(Product, [[id: 1, name: "Test Product"]])
Product.metaClass.delete = {-> throw new DataIntegrityViolationException("I'm an exception")}
controller.delete(1)
assertEquals(view, '/show/edit')
}
Controller action code:
def delete(Long id) {
def productInstance = Product.get(id)
if (!productInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'product.label', default: 'Product'), id])
redirect(action: "list")
return
}
try {
productInstance.delete(flush: true)
flash.message = message(code: 'default.deleted.message', args: [message(code: 'product.label', default: 'Product'), id])
redirect(action: "list")
}
catch (DataIntegrityViolationException e) {
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'product.label', default: 'Product'), id])
redirect(action: "show", id: id)
}
}
When I run the test, productInstance.delete(flush: true) does not throw the exception I’m expecting. Instead it redirects to action: "list". Does anyone know how to override the Product.delete() method so I can force the exception?
You’re mocking
deletewithout any arguments, but your controller callsdelete(flush: true). Try mocking outdelete(Map)like this: