Using InjectMock on Object with private static final fields failing - testing

I am writing test cases for a legacy code which for some reason we dont want to change.
The code is something like this
public class ToBeTested{
private static final String field1=SomeUtil.getProperty("somekey");
#AutoWired
Someservice service;
}
In my Junit I am using powermock with mockito and did something like this
public class myTestClass{
#Mock
SomeService service;
#InjectMock
ToBeTested tested;
}
However, InjectMocks fails to create the object for ToBeTested since the final fields are not provided
So I implemented a #BeforeClass and mocked the static method of SomeUtil. This works if i have only one test case. But for more than one test case, only one passes and others are failing with same error that
cannot instantiate #injectmocks field named you haven't provided the instance at field declaration
I have been able to resolve this by using something as below:
public class myTestClass{
#Mock
SomeService service;
ToBeTested tested;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
mockStatic(SomeUtil.class);
when(SomeUtil.getProperty(anyString())).thenReturn("test");
toBeTested=new ToBeTested(); Whitebox.setInternalState(toBeTested,"someService",someService);
}
}
However am not a fan of using reflection in Junit which WhiteBox does internally.
Is there a better way to do this?
Edit: Adding the snippet of code as suggested by Rann in comment
#RunWith(PowerMockRunner.class)
#PrepareForTest(SomeUtil.class)
public class myTestClass{
#Mock
SomeService service;
#InjectMock
ToBeTested tested;
#BeforeClass
public static void doBeforeClass(){
mockStatic(SomeUtil.class);
when(SomeUtil.getProperty(anyString())).thenReturn("test");
}
#Test
public void test1(){
tested.doSomethingFor1();
}
#Test
public void test2(){
tested.doSomethingFor2();
}
}
test1 passes fine. for test2 i get an exception as
Caused by: org.mockito.exceptions.base.MockitoException:
Cannot instantiate #InjectMocks field named 'tested' of type 'class com.xyz.ToBeTested'.
You haven't provided the instance at field declaration so I tried to construct the instance.
However the constructor or the initialization block threw an exception : null
at org.powermock.api.extension.listener.AnnotationEnabler.injectSpiesAndInjectToSetters(AnnotationEnabler.java:72)
at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:64)
at org.powermock.tests.utils.impl.PowerMockTestNotifierImpl.notifyBeforeTestMethod(PowerMockTestNotifierImpl.java:82)
... 23 more
Caused by: java.lang.NullPointerException
at com.xyz.SomeUtil.getProperty(SomeUtil.java:42)

Related

JUnit parametrized in Before method executes later and throws ParameterResolutionException

I have test class that consists of #Before method with some parameters, and other test methods.
#Before
#ParameterizedTest
#ValueSource(strings = {"123", "456"})
public void createData(String userId) {
someMethod(userId)
}
#ParameterizedTest
#ValueSource(strings = {"123", "456"})
public void abc(String userId) {}
but it keeps executing abc() first and throws error
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [java.lang.String arg0] in method [public void tests.xxx.createData(java.lang.String) throws java.io.IOException].
I'm quite new to JUnit Parameters. Can Before method be at the same time ParametrizedTest? Without this annotation [ParametrizedTests] it seems not to work as intended, but on the other hand I need this to execute before all other methods. What might be the issue and what's the solution?

Is there a way to have the #MethodSource arguments parameters derived from another method

I have a Junit 5 non static parameterized test where I am using #MethodSource to get the test data.
The Method Source arguments are getting the data from other methods as below code. I made the #MethodSource non static by having a
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
The fullDomain parameter in the #MethodSource is derived from the method getFullDomain() in the registrationPage which is also non static . I #Autowired the RegistrationPage in the BaseTest and using it by extending in my Junit5SampleTest Class
When I run the test the fullDomain is returning null. Is there a way to fix this or can I use any others like #ArgumentSource to fix this.
I will need to get the Arguments.of("Successful Regisration", fullDomain) data from different classes and its methods.
Base Test:
public class BaseTest {
#Autowired
protected RegistrationPage registrationPage;
}
Test Class:
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Junit5SampleTest extends BaseTest {
String fullDomain = registrationPage.getFullDomain();
Stream<Arguments> registrationInputParameters() {
return Stream.of(
Arguments.of("Successful Regisration", fullDomain)
}
#ParameterizedTest()
#MethodSource("registrationInputParameters")
public void junit5(String testName, String fullDomain){
System.out.println(testName);
open(fullDomain);
}
}

How to use arquillian to test EJB calling webservices using #webserviceref annotation

I'm trying to use arquillian to test one method of an EJB using a webservice through #WebServiceRef annotation
In my method decorated by #Deployment I declared the resource
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create(JavaArchive.class)
.addPackages(true, .... PortType.class.getPackage())
.addAsResource("test-my.wsdl","my.wsdl")
.addAsManifestResource("META-INF/beans.xml", "beans.xml").addAsManifestResource("META-INF/test-persistence.xml", "persistence.xml");
}
Then I coded the bean as following
#Stateless
#LocalBean
public class WSBean {
#WebServiceRef(wsdlLocation = "/my.wsdl")
PortType portType;
public void test() throws Exception{
portType.lireAdresseClient(null, null);
}
}
and the test
#RunWith(Arquillian.class)
public class WSintegrationTest extends DefaultServicesIntegrationTest {
#Deployment
....
#Inject
private WSBean wsBean;
#Test
public void testAppel() throws Exception {
System.out.println("TEST APPEL");
wsBean.test();
}
}
Can I do that with Arquillian ?
How can I fix it ?
Thanks
Regards
Also if you want you can take a look at https://github.com/javaee-samples/javaee7-samples/tree/master/jaxws you will find examples of JAXWS with its Arquillian test.

Unable to inject dependencies of injected bean with Arquillian

I am using Arquillian to inject the dependencies for my tests. It works OK if I inject the beans directly to my test class, but if the beans have dependencies of their own tht have to be injected, those dependencies do not get injected.
For example: the FacLptConfiguration bean gets imported correctly into my Test Class, but it does not get injected into the CfdFileCreator bean. I injected FacLptConfigurtion to the test class just to confirm that the injection works, but the user of this class is CfdFileCreator.
#RunWith(Arquillian.class)
public class CfdFileCreatorArquillianTest {
#Deployment
public static WebArchive createDepolyment() {
return ShrinkWrap.create(WebArchive.class)
.addClass(FacLptConfiguration.class)
.addClass(InterimFileCreator.class)
.addClass(CfdFileCreator.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(new File("C:/aLearn/FacLpt/web/WEB-INF/env-entries.properties"));
}
public static String TEST_FOLDER = "C:/aLearn/FacLpt/src/test/testdata/pruebas/";
#Inject
private FacLptConfiguration facLptConfiguration;
#Inject
private CfdFileCreator cfdFileCreator;
#Test
public void createCfd() {
System.out.println("in createCFD");
cfdFileCreator.createCFDFile();
}
}
These injections are not working:
#Singleton
public class CfdFileCreator {
#Inject
private InterimFileCreator interimFileCreator;
#Inject
private FacLptConfiguration facLptConfiguration;
I think your problem is the location of the beans.xml. For a web archive it should be WEB-INF/beans.xml. Use:
addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"))
See also https://community.jboss.org/thread/175404

bind to property always return null

I am trying to bind a repository to property using Ninject but always get null reference of binding object. I will explain the problem using code below.
public interface IServiceRepository
{
User GetUser(string email);
IQueryable<Statistic> GetStatisticForCurrentMonth(string ip);
void InsertStatistic(ConversionModel conversionModel);
class ServiceRepository : IServiceRepository
{
//Implementation of the Interface
}
I am would like to bind the repository above to class below while the class is created. Unfortunately Repository object is always null. Maybe I have misunderstood how Ninject is working? How to solve the problem?
public class Converter
{
[Inject]
public static IServiceRepository Repository { get; set; }
private static Converter _converter;
public static Converter Instance
{
get { return _Converter ?? (_Converter = new Converter ());
}
}
Ninject activator code
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IServiceRepository>().ToMethod(context => Converter.Repository);
}
Update
I have tried to rewrite code like this
public class Converter
{
private readonly IServiceRepository _repository;
public Converter(IServiceRepository repository)
{
_repository = repository;
}
//skip code
}
The test...
[TestMethod]
public void ConverterInstanceCreated()
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IServiceRepository>().To<ServiceRepository>();
Assert.IsNotNull(kernel.Get<Converter>());
}
}
gives exception
Test method PC.Tests.NinjectTest.ConverterInstanceCreated threw exception:
Ninject.ActivationException: Error activating IServiceRepository
No matching bindings are available, and the type is not self-bindable.
Activation path:
2) Injection of dependency IServiceRepository into parameter repository of constructor of type Converter
1) Request for Converter
I just lost, I am trying to understand how Ninject is working for about week without any success. In my case why this exception is thrown?
Also please someone post working example with one repository injection to singleton class.
Ninject does not inject statics. Change the coynverter to a non-static class and configure it as Singleton in ninject. Also use constructor injection and make the repo a private field.
Now you can inject the converter to the constructors where you need it.
Even though you are using Property injection and not Constructor injection I think it would still be
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IServiceRepository>().To<ServiceRepository>();
}
As ninject still just needs to know what concrete type to map to the Interface
I haven't tested this so apologies if it's wrong.