class AbstractXYZClass{
...
#AroundInvoke
public Object intercept(InvocationContext ctx) ... {
log("do intercepting");
ctx.proceed();
}
...
}
#Stateless
class XYZClass extends AbstractXYZClass{
...
public void iWantToTestThisMethod() {...}
...
}
(running this on Server the interception for iWantToTestThisMethod() works fine)
In my unit tests (using Needle ...#ObjectUnderTest(implementation=XYZClass.class)...) #AroundInvoke doesn't get invoked
How can I JUnit-test XYZClass::iWantToTestThisMethod with intercept() intercepting?
Needle4j is a dependency injection "simulator", it does not support advanced lifecyles and scopes. So you will have to come up with a different testing strategy.
I would stick to needle4j when it comes to injection and verification of correct method interactions but switch to something like CDI-Unit or Arquillian for the actual framework-behavior tests.
Related
I am setting some properties as below when I launch the Junit Tests programmatically.
LauncherDiscoveryRequestBuilder
.request()
.selectors(selectMethod("com.example#testMethod()"))
.configurationParameter("My_Param","Hello")
.build()
Is there a way to access My_Param from the test method?
I believe you can use the ExtensionContext.getConfigurationParameter() method.
From JUnit 5.1.0 release notes:
Extensions for JUnit Jupiter can now access JUnit Platform configuration parameters at runtime via the new getConfigurationParameter(String key) method in the ExtensionContext API.
The obvious way to access the ExtensionContext would be to implement an extension.
An alternative would be to implement one of the lifecycle callbacks directly in the test:
public class YourTest implements BeforeEachCallback {
#Override
public void beforeEach(ExtensionContext context) throws Exception {
}
}
I am using Arquillian and TestNG with CDI.
Before each test I need access to some members that are CDI beans to do some setup before each test. But i noticed that in every #Before annotation the CDI beans were not injected, but in the #Test annotated method they are.
Can someone explain me why:
1) CDI beans are not yet injected in the #BeforeXXX annotated methods part of the test life cyle?
2) How can I do some setup and access CDI beans before the Tests?
3) Would be correct used the "dependency" attribute in the #Test annotation?
Thank you so much.
I think I already understood the problem.
The tests run in two different places:
- in the client: maven jvm
- in the container: server jvm
In the client side, the CDI beans are not available in the #BeforeMethod, but they will when the test is running in the container. Basically if we need to access CDI beans in the before method we just need to make sure that the test is running in the container. To accomplish this i created a class that extends Arquillian and expose a method that does this.
public abstract class BaseArquillianTest extends Arquillian {
#ArquillianResource
protected InitialContext initialContext;
#Deployment
#OverProtocol("Servlet 3.0")
public static WebArchive createDeployment() {
WebArchive war = PackagingUtil.getWebArchiveForEJB();
return war;
}
protected boolean inContainer() {
// If the injection is done we're running in the container.
return (null != initialContext);
}
}
We just have to do this check in #BeforeMethod method
#BeforeMethod(alwaysRun = true)
public void beforeMethod() throws Exception {
System.out.println("********* Initing beforeMethod");
if(inContainer()) {
System.out.println("$$$$$$ I am in a container");
Assert.assertNotNull(allRiskConfigurations);
} else {
System.out.println("$$$$$$ I am NOT in a container");
}
}
In the end, the tests in the client looks like they are ignored to reflect the results of the tests that were executed in the container.
If this is wrong, can someone please correct?
Thank you all anyway. I Hope this help
I am writing tests with Arquillian embedded. But i am facing issue when my bean is in View Scope. I just posted my sample code. When my DataBean is in ViewScope it doesn't run and throws some exception. But when i changed it to RequestScope it worked fine.
#RunWith(Arquillian.class)
public class MockTest {
#Deployment
public static Archive<?> createDeployment() {
JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
.addClass("pack.ui.DataBean")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return jar;
}
#Inject
private DataBean dataBean;
#Test
public void testDataBean() throws Exception {
dataBean.checkSystemStatus();
Assert.assertEquals(status, true);
}
#ViewScoped
#Named("dataBean")
public class DataBean {
public boolean checkSystemStatus() {
return true;
}
}
Can someone please tell, Can we use ViewScope with Arquillian or anything else i have to do.
It's because the view scope is not active during the invocation of your test. To run it this way, you'll need to use something like drone/graphene. It's not active because the HTTP request that runs is against the arquillian test runner servlet, not the webpage of your application. ViewScope is specific to a page in your application.
You can mock JSF context of controllers and get rid of annoying exception "No active contexts for scope type ViewScoped" during Arquillian test execution.
Check the original project for JSF 2.0: https://github.com/it-crowd/mock-contexts-extension
or my upgrade for JSF 2.2: https://github.com/kesha/mock-contexts-extension
All you need is the additional annotation #ViewScopeRequired before the test method.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations={"/applicationContext-test.xml"})
#Transactional
public class MyServiceTest {
#Resource(name="myService")
public MyService myService;
#Test
public void testSeomthing() {
//do some asserts using myService.whatever()
}
}
However the tests are based on data I migrate in, so every time I run my suite of tests I want to execute my unrelated migration code. I don't want to run a #Before in each test class. I want to run it once at beginning of complete test process, where can I put this ?
I would advice you to create a test bean somewhere with startup logic invoked in #PostConstruct:
#Service
public class TestBean {
#PostConstruct
public void init() {
//startup logic here
}
}
Obviously this bean should only be created for tests, the easiest way to achieve this is to place it in src/test/java in a package that is component-scanned by Spring for #Service-annotated classes.
Note: you must remember that #PostConstruct is not running in a transaction! See How to call method on spring proxy once initialised.
JUnit also offers a #BeforeClass annotation which you can place on a static method to initialize resources just once.
I have a Jersey Resource that I want to test with JUnit. The resource uses Guice Providers to inject certain fields:
#Path("/example/")
class ExampleResource {
#Inject
Provider<ExampleActionHandler> getMyExampleActionHandlerProvider;
#GET
#Produces(MediaType.APPLICATION_JSON)
public List<ExamplePojo> getExampleList() {
ExampleActionHandler handler = getMyExampleActionHandlerProvider.get();
handler.doSomething();
...
This all works beautifully when using a real server to serve the API, however testing it is problematic.
My test class currently looks something like:
public class ApiTest extends JerseyTest {
public ApiTest() throws Exception {
super();
ApplicationDescriptor appDescriptor = new ApplicationDescriptor();
appDescriptor.setContextPath("/api");
appDescriptor.setRootResourcePackageName("com.my.package.name");
super.setupTestEnvironment(appDescriptor);
}
#Test
public void testHelloWorld() throws Exception {
String responseMsg = webResource.path("example/").get(String.class);
Assert.assertEquals("{}", responseMsg);
}
}
Clearly, Guice isn't getting the opportunity to initialize the fields in ExampleResource so that the handler.doSomething() call doesn't result in a NullPointerException.
Is there a way to tell Jersey to instantiate the ExampleResource class using Guice so that the Provider works?
One way to do it is to break the tests to few steps. You need to create the injector you're configuring the service with and test that injector (see Testing Guice Servlet bindings and Testing Guice can init servlets). Using these tests you make sure you have the right bindings in place.
Once you have the injector, get the ApplicationDescriptor object from it with
ExampleResource exampleResource = injector.getInstance(ExampleResource.class);
Assert.assertEquals(myList, getExampleList());