Best way to only run #BeforeClass method - ant

I have a test class that has a #BeforeClass method and a #Test method. I am running the tests using Ant. I would like to know what is the best way to run only the #BeforeClass method, and not the #Test method. Here is the basic code layout:
#BeforeClass
public void init() throws Exception {
/* Perform test initialization */
}
#Test
public void randomTest() throws Exception {
/* Run the test */
}
I have tried making the #Test method part of a group, and then in Ant specifying the "excludedgroups" property to exclude that group. I have also tried setting the #Test method to be disabled. Neither of these methods worked because it wouldn't run either the #Test or the #BeforeClass method.
One workaround I have is to make an empty #Test method, and then use either method above, but this does not seem like an elegant solution.
Is there a better way to run only the #BeforeClass method?
Edit:
Here is how I specify the task in my build.xml file:
<testng classpathref="test.classpath"
outputdir="${reports}"
haltonfailure="false"
failureProperty="tests.failed"
useDefaultListeners="true" listeners="org.uncommons.reportng.HTMLReporter,org.uncommons.reportng.JUnitXMLReporter"
parallel="classes"
suitename="Tests"
testname="${test.name} Tests">

Disabling the #Test method will work but you will have to have at least one test method on your class or TestNG won't run anything in it, so maybe add an empty test method? It's kind of an odd scenario to run a class just for its configuration method, are you sure this configuration cannot be put in another class?

If you change it to #BeforeSuite it is run without needing an empty #Test method and excluding the method. You can also disable the test method directly with #Test(enabled=false).

I ultimately decided to just put an if statement around every #Test method, and have the statement evaluate a System property.

Related

Why is sessionFactory not injected for unit test using Grails 3.2?

I'm running into an issue where a unit test that extends HibernateSpec is failing due to the sessionFactory not being injected into the service under test. Whenever a method on the sessionFactory is called during the test, I get a NullPointerException (e.g. java.lang.NullPointerException: Cannot invoke method getClassMetadata() on null object) and the test subsequently fails.
I'm using Grails 3.2.4 and Hibernate 5.
This was working when the test used #TestMixin(HibernateTestMixin), but it looks like with some updates, the mixin is deprecated and suggests using HibernateSpec instead.
Here's a snippet from my test:
class TestDatabaseServiceSpec extends HibernateSpec {
def setup() {
}
def cleanup() {
}
void "test method"() {
when:
service.method()
then:
true
}
}
And here is a snippet from the service under test:
void method() {
...
TABLE_NAMES.add(sessionFactory.getClassMetadata('MyDomain').tableName)
...
}
I have tried to set service.sessionFactory in setup method as well as setupSpec method with the sessionFactory available in the test, but that did not help unfortunately. I have thought about using an integration test, but I would really like to see if I can continue to have this unit test work as it was before. Does anyone know if I am I doing something incorrectly or if there is a workaround/solution for this?
Thank you!
Viewing source code of HibernateSpec could give some hint. Could be there is no getSessionFactory() method in Hibernate 5 grails plugin that you are using.
I am using org.grails.plugins:hibernate5:6.0.6 with grails 3.2.5 and sessionFactory is not null for me in unit tests.
I understand that it is not always possible to upgrade, but it could give an idea what is the source of the problem.
Update:
service.sessionFactory = sessionFactory
also must be called in test setup.
What worked for me was to add the annotation #FreshRuntime to the spec and to add a doWithSpring closure to the test that sets up the sessionFactory for me (i.e. sessionFactory(InstanceFactoryBean, sessionFactory, SessionFactory)). Also, I made sure to add both service.sessionFactory = sessionFactory and service.transactionManager = transactionManager to the setupSpec method. Finally, I needed to override getDomainClasses() to work with all of the domain objects I wanted to in the test. Thanks for all the help!
The Test Mixins have been deprecated for the new traits since 3.2.3.
https://docs.grails.org/latest/guide/testing.html
Since Grails 3.3, the Grails Testing Support Framework is used for all
unit tests. This support provides a set of traits.
However, I still find myself using HibernateSpec as I can get multiple Domain classes from that, and the ServiceUnitTest for the service as well. The HibernateSpec has the needed sessionFactory.
E.g.
class MyServiceSpec extends HibernateSpec implements ServiceUnitTest<MyService>{
List<Class> getDomainClasses() { [Tag, TagLink, TagLinkValue, TagValue, TestDomain] }
...
def setup() {
service.sessionFactory = sessionFactory
...
}
// tests here with all those domain classes available and the service
}
The DataTest allows for multiple domain classes, but not the service as well.
https://testing.grails.org/latest/guide/index.html#unitTestingDomainClasses
the service test allows for the service, but not multiple domain classes.
https://testing.grails.org/latest/guide/index.html#unitTestingServices
You could use both of them together, but neither one of them has the session factory (that I could see), I'm on Grails 4.0.1. I looked through Github code for the latest and still don't see it available. Plus, the DataTest doesn't a hibernate session, it uses a SimpleMap instead so you can't use hql with it, which I wanted.
My Service was using the statelessSession
def statelessSession = sessionFactory.openStatelessSession()
String queryString = "select DISTINCT(t.tagRef) from com.fmr.aps.taggable.TagLink t group by t.tagRef order by t.tagRef ASC"
Query query = statelessSession.createQuery(queryString)
query.setReadOnly(true);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
So I needed a unit test trait or base class with it and I spent several hours trying to make the new traits give me what I wanted. Even I began subclassing the DataTest class to try and make it give me the sessionFactory, but eventually just went with the HibernateSpec and it's nice to be able to run that one test class with several Domains, the Service and the sessionFactory.

How to login before executing Geb tests

I've got REST webservice based on Grails. There's obligatory authentication before you can access any page except login.
I use Geb & Spock for integration tests, running through Gradle. My question is: how can I provide authentication before executing any test?
I have 2 ideas:
Run tests in order (log in at first, then run others). How? (must be triggering by command gradle integrationTest)
Execute JS script before every test which authenticate me. How to implement this in test?
What kind of authentication?
For Basic authentication have a look at:
HTTP Basic Authentication credentials passed in URL and encryption
so you could just add that to your base url.
If you have to go through the login process, you can use the setupSpec() and setup methods. The former gets executed before anything else happens, the latter before each individual test method.
You can use the #Stepwise notation to stop cookies from being deleted between test methods.
If you have different geb classes and want all of them to be prepended with your setup or setupSpec method, use the extends notation:
class BaseClass extends GebSpec {
def setupSpec() {
<loginProcess>
}
}
#Stepwise
class ASpec extends BaseClass {
testMethod() { }
}
#Stepwise
class BSpec extends BaseClass {
testMethod() { }
}
note that this will execute the login process one extra time because it happens in the BaseClass as well.
I got around this with an if (this.getClass().getPackage().getName() != "gebMethods") block but I guess there might be a more elegant solution.
If it's a web service I'd not use Geb for testing it. Geb is a tool for driving browsers and REST web services are best tested using http clients, like REST-assured.
I would make authentication configurable in the app and disable it for most tests apart from ones that explicitly test authentication.

How to mockup an entityManager for unit testing a service

I´m trying to write some unit tests for my company, so its not possible for me to change anything in sourceCode but everything in the tests.
I´m using Java8, Spring, Mockito and JUnit4.
Problem: There are some services with a entityManager, which gets instantiated via dependencyInjection
#PersistenceContext(unitName = someName)
private EntityManager em;
I tried to mock this and injecting it into my ClassUnderTest, like i mocked every other class but that doesn´t work.
#InjectMocks
#Autowired
private SomeService testedSomeService;
There´s always an "IllegalStateException: Failed to load application context" before running the first test, with a hint to the entity manager.
If i make the annotation to a comment, every method gets tested fine (except the methods, using entityManager).
Is there a simple way to mock the entityManager? or how can i inject a dependency in my testclass?
I appreciate ANY help!
Try this:
#RunWith(MockitoJUnitRunner.class)
public class Test {
#Mock
private EntityManager em;
#Before
public void setUp(){
MockitoAnnotations.initMocks(this);
Mockito.reset(em);
}
//your junits
}
Of course you can. You use #Mock, that's all. #InjectMocks is for the service which uses EntityManager, not for EntityManager. And #Autowired is for real instanciation and injection via context, which only exists in an integrated test, not in an unit test, as what you do here.
Just use #Mock.

Grails3 controller integration test case fail: No thread-bound request found

With just simple following controller action spock integration-test. Here is my Test.
#Integration
#Rollback
class TestControllerSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
setup:
def c = new TestController()
c.index()
expect:
c.response.contentType !=null
}
}
getting following Exception
java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131)
at grails.web.api.WebAttributes$Trait$Helper.currentRequestAttributes(WebAttributes.groovy:45)
at grails.web.api.ServletAttributes$Trait$Helper.getRequest(ServletAttributes.groovy:42)
I've been doing this and it seems to work fine:
Add field:
#Autowired
WebApplicationContext ctx
In setup():
GrailsWebMockUtil.bindMockWebRequest(ctx)
In cleanup():
RequestContextHolder.resetRequestAttributes()
Unfortunately it might be a limitation in Grails 3, that you cannot use integration tests to test controllers.
To integration test controllers it is recommended you use
create-functional-test command to create a Geb functional test.
Source from Grails documentation
This seems to be a major change of direction from previous versions of grails. If you really need to test a controller in an integration test, you could try doing this:
NOTE: I realize this might be a bad practice, and it goes against Grails documentation, but sometimes you also need to test things more programmatically, where unit tests aren't sufficient, and are Geb tests aren't granular enough.
#TestFor(TestController) // This will provide a mocked "controller" reference
#Integration
#Rollback
class TestControllerSpec extends Specification {
// If TestController uses any services, have them autowired into this test
#Autowired
SomeService someService
def setupSpec() {
// Now connect those services to the controller
controller.someService = someService
}
void "test something"() {
when:
controller.index()
then:
response.contentType != null
}
}
WARNING: After some additional work with this format I did find a problem. Using #TestFor will call Holders.clear() when it is complete, which means that there will not be a grailsApplication object in Holders. This will cause problems if you have any integration tests that run after one that uses the approach above. After much digging, it doesn't look like there is an easy (or even hard) way of making this work, which is possibly why it is not supported in Grails 3. That being said, one option is to mark other integration tests with #TestFor, so that the Holders class will be properly populated. Is this a hack? Yes it is! You will need to decide if it is worth the effort of adding this overhead to all tests. In my case it was only one other integration test that needed this (as it is a small application), but if it was more than that I would not use this approach.

GRAILS 2.4.4: how to run unit tests only, or how to fix the generated integration tests?

With grails 2.4, when you create a controller for example, it creates a unit test class such as:
#TestFor(SessionService)
class SessionServiceSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
}
}
so you create 20 controllers, and get 20 test classes.
When you try to run grails test-app, it fails with the following error:
java.lang.Exception:
No tests found matching grails test target pattern filter from org.junit.runner.Request
It never gets to run our integration tests.
So tests Grails creates for you do not work out of the box.
We could delete all the created test specs classes, but then we kind of want them there ready for if we want to write them.
is there a way to run our integration tests, without running the unit tests (which are broken) or:
is there a way to fix the test so they don't fall over? Someone posted add a valid when/then, but we don't know what to put in this, as what we have tried still generates the same exceptions.
It's a shame Grails doesn't tell you which tests or class throws this exception.
This looks like a weird argument to me. When you create a controller, unit spec is created for it by default based on a template which can be easily tailored according to your need.
grails install-templates
does it for you. Now to answer your questions:
Yes there is a way to only run integration tests.
grails test-app integration:
After using install-templates modify the Controller.groovy template under src\templates\testing to something
like:
#artifact.package#import grails.test.mixin.TestFor
import spock.lang.Specification
/**
* See the API for {#link grails.test.mixin.web.ControllerUnitTestMixin}
* for usage instructions
*/
#TestFor(#artifact.testclass#)
class #artifact.name# extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
expect:
1 == 1
}
}
This will not fail your test when run but it defeats the whole purpose of
writing failing test -> modify code -> fixing test approach
of TDD. I would rather implement a failing test and then write minimal logic in controller to pass the test.

Resources