unit testing src/groovy class files - unit-testing

I'm working on unit tests for a grails application. I've been successful at testing services and domains but stuck trying to test classes in the src/groovy folder. What do I have to do to access the saveCreateAndCall method?
#Artefact("Controller")
#Transactional(readOnly = true)
class BaseController<T> extends RestfulController<T> {
protected def saveCreateAndCall(Object instance, boolean flush = false, Closure c) {
if (instance.save(flush: flush)) {
c.call instance
} else {
errorCreateResponse(instance)
}
}
any advice or feedback would be appreciated, thanks

You can create your BaseController as an abstract class and let it in the controllers folder.
abstract class BaseController<T> {
}
Normally I tend to create an concrete controller to test my base abstraction and use the #TestFor to use the Grails testing features for controllers.
Or you can annotate your test:
#GrailsUnitTestMixin
#Mock(MyDomainClass)
class BaseControllerTest extends Specification {
}

Related

Mock #AuthenticationPrincipal MockMvc with addFilters = false

I am using mockMvc to write unit tests for Controllers in Rest Application.
I am facing challenge in testing below rest End Point -
#GetMapping("/details")
public ResponseEntity<UserDetails> getUserDetails(#AuthenticationPrincipal UserDetails userDetails)
{
return ResponseEntity.ok(userDetails);
}
As you can see , I need to mock #AuthenticationPrincipal to get this rest end Point unit tested
Now the challenge is the unit test class I am using has below skeleton :
public class ControllerTest extends BaseControllerTest{
}
and BaseControllerTest is :
#WebMvcTest
#ContextConfiguration(
classes = {
TestClass1.class,
TestClass2.class,
})
#AutoConfigureMockMvc(addFilters = false)//here is a problem
#TestExecutionListeners(MockitoTestExecutionListener.class)
#ActiveProfiles("test")
public class BaseControllerTest extends AbstractTestNGSpringContextTests {
}
So as you can see all filters are disabled as we are usig addFilters = false.
When I debugged the unit tests with eclipse I can see NO SPRING SECURITY FILTERS are being added in call chain as addFilters = true
I have searched a lot on public forum and it seems using annotations like #WithUserDetails and #WithMockUser , it is possible to achieve this.
But these will not work as there is no spring security behind the scenes
Can anybody please help here ?

Unit testing with a mock EntityManager when using JPA in Play

I have some (Scala) code in Play which uses JPA for DB access. Works fine. But I want to unit test my code, which will require using a mock EntityManager. Is this possible?
My test is written in specs2 (by extending PlaySpecification) and is run with JUnit. I am using Mockito to mock the EntityManager. But I would expect to be able to do this with other frameworks.
Here's what my code looks like:
object MyThing {
def create(...) : MyThing = {
val newThing = ...
JPA.withTransaction(new play.libs.F.Function0[Unit]() {
def apply() = {
JPA.em().persist(newThing)
}
})
return newThing
}
}
If it is not possible to unit test this code, is there some alternate approach to data access which is recommended?
Apparently there is no way to use a mock EntityManager here, at least none that I could find. So I had to revise my design.
Will Sargent of Typesafe suggested creating a separate DB persistence subproject on the mailing list: https://groups.google.com/d/msg/play-framework/1u-_JbTIuQg/L5_9o4YCfoMJ. I haven't gone quite that far, but I did find a solution that worked for me by defining a separate DAO interface.
I put all the JPA code into a DAO trait - all the implementation is in there. There's also a companion object to provide a singleton instance. Like so:
trait MyThingDAO {
def create(...) : MyThing = { ... }
}
object MyThingDAO extends MyThingDAO
Now I change my controllers to traits, with a reference to the DAO left unset. A companion object sets the DAO instance to the singleton object. This avoids making any changes to the routes file (no need to instantiate the controllers). Like so:
trait MyThingController {
val myThingDao : MyThingDAO
def myAction = Action { implicit request => ... }
}
object MyThingController {
val myThingDao = MyThingDAO
}
So everything works easily enough with the standard JPA code when the app is running. But when I want to unit test, I can insert a mock DAO like so (this is using Mockito):
...
val mockDao = mock[MyThingDAO]
val controller = new MyThingController() { val myThingDao = mockDao }
...
Maybe this isn't the ideal approach, but it has been working so far. I would still be interested to hear any other suggestions.

#Mock domain objects in unit testing in grails listOrderBy dynamic finder throws an exception

I am writing a unit test for a grails controller. Here is a snippet of the code:
#TestFor(MyController)
#Mock([MyDomain])
class MyControllerTests {
void testController() {
...
...
}
}
Here is how the domain object looks like:
class MyDomain {
static constraints = {
name(nullable: false)
parent(nullable: true)
}
static belongsTo = Industry
static hasMany = [children: Industry]
Industry parent
String name
}
The method in the controller I am testing calls this GORM dynamic method:
MyDomain.listOrderByParent()
The test fails when execution hits this line and the exception is not making much sense to me since the #Mock annotation should have added all the dynamic methods:
groovy.lang.GroovyRuntimeException: Cannot compare com.stuff.MyDomain with value 'com.stuff.MyDomain : 1' and com.stuff.MyDomain with value 'com.stuff.MyDomain : 4'
at org.grails.datastore.mapping.simple.query.SimpleMapQuery$_executeQuery_closure63_closure155.doCall(SimpleMapQuery.groovy:78)
The controller works fine when running the grails app. Any ideas?
You may mock the Industry domain object
as well:
#Mock([MyDomain, Industry])

Moq custom IIdentity

I created a custom RoleProvider (standard webforms, no mvc) and I would like to test it. The provider itself integrates with a custom implementation of IIdentity (with some added properties).
I have this at the moment:
var user = new Mock<IPrincipal>();
var identity = new Mock<CustomIdentity>();
user.Setup(ctx => ctx.Identity).Returns(identity.Object);
identity.SetupGet(id => id.IsAuthenticated).Returns(true);
identity.SetupGet(id => id.LoginName).Returns("test");
// IsAuthenticated is the implementation of the IIdentity interface and LoginName
However when I run this test in VS2008 then I get the following error message:
Invalid setup on a non-overridable member: id => id.IsAuthenticated
Why is this happening? And most important, what do I need to do to solve it?
Grz, Kris.
You should mock IIdentity (instead of CustomIdentity - only possible if the variables you are mocking are declared in the interface) or declare the used variables as virtual.
To mark as virtual, do this: In your concrete class CustomIdentity, use
public virtual bool isAuthenticated { get; set; }
instead of
public bool isAuthenticated { get; set; }
Moq and other free mocking frameworks doesn't let you mock members and methods of concrete class types, unless they are marked virtual.
Finally, you could create the mock yourself manually. You could inherit CustomIdentity to a test class, which would return the values as you wanted. Something like:
internal class CustomIdentityTestClass : CustomIdentity
{
public new bool isAuthenticated
{
get
{
return true;
}
}
public new string LoginName
{
get
{
return "test";
}
}
}
This class would be only used in testing, as a mock for your CustomIdentity.
--EDIT
Answer to question in comments.
Are you mocking against the interface IIdentity, or mocking against your custom type?
Without having a fuller code snippet to look at, I am guessing that it is complaining that the IsAuthenticated is not marked as virtual in your custom implementation. However, this could only be the case if you were mocking against the concrete type, not the interface.

Best Way to Unit Test a Website With Multiple User Types with PHPUnit

I'm starting to learn how to use PHPUnit to test the website I'm working on. The problem I'm running into is that I have five different user types defined and I need to be able to test every class with the different types. I currently have a user class and I would like to pass this to each function but I can't figure out how to pass this or test the different errors that could come back as being correct or not.
Edit: I should have said. I have a user class and I want to pass a different instance of this class to each unit test.
If your various user classes inherit from a parent user class, then I recommend you use the same inheritance structure for your test case classes.
Consider the following sample classes:
class User
{
public function commonFunctionality()
{
return 'Something';
}
public function modifiedFunctionality()
{
return 'One Thing';
}
}
class SpecialUser extends User
{
public function specialFunctionality()
{
return 'Nothing';
}
public function modifiedFunctionality()
{
return 'Another Thing';
}
}
You could do the following with your test case classes:
class Test_User extends PHPUnit_Framework_TestCase
{
public function create()
{
return new User();
}
public function testCommonFunctionality()
{
$user = $this->create();
$this->assertEquals('Something', $user->commonFunctionality);
}
public function testModifiedFunctionality()
{
$user = $this->create();
$this->assertEquals('One Thing', $user->commonFunctionality);
}
}
class Test_SpecialUser extends Test_User
{
public function create() {
return new SpecialUser();
}
public function testSpecialFunctionality()
{
$user = $this->create();
$this->assertEquals('Nothing', $user->commonFunctionality);
}
public function testModifiedFunctionality()
{
$user = $this->create();
$this->assertEquals('Another Thing', $user->commonFunctionality);
}
}
Because each test depends on a create method which you can override, and because the test methods are inherited from the parent test class, all tests for the parent class will be run against the child class, unless you override them to change the expected behavior.
This has worked great in my limited experience.
If you're looking to test the actual UI, you could try using something like Selenium (www.openqa.org). It lets you write the code in PHP (which I'm assuming would work with phpUnit) to drive the browser..
Another approach would be to have a common method that could be called by each test for your different user type. ie, something like 'ValidatePage', which you could then call from TestAdminUser or TestRegularUser and have the method simply perform the same basic validation of what you're expecting..
Just make sure you're not running into an anti-pattern here. Maybe you do too much work in the constructor? Or maybe these should be in fact different classes? Tests often give you clues about design of code. Listen to them.