PowerMockito whenNew returns null - java

In the source class that which I can't refactor (so i can't use advices here) there are object creations with = new XXX. And i have to mock their function calls X().call().
For this purpose i am using powermock's whenNew() function. But i am having null in the class that i am testing which is LoginSuccessHandler in this case. Here my LoginSuccessHandlerTest class:
#RunWith(PowerMockRunner.class)
public class LoginSuccessHandlerTest {
#InjectMocks private LoginSuccessHandler loginSuccessHandler;
#Mock private GuiSessionDAO guiSessionDAO;
#Mock private UserAuthorityDAO userAuthorityDAO;
#Mock private OrcaAuthorizationServiceBean orcaAuthorizationServiceBean;
#Mock private OrcaAuthorizationServiceBeanService orcaAuthorizationServiceBeanService;
#Mock private GetUserRolesReturnModel userRolesReturnModel;
private Authentication authentication;
private MockHttpServletRequest request;
private MockHttpServletResponse response;
#Before
public void setUp() {
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
authentication = new TestingAuthenticationToken("foo", "foo", "foo");
}
#PrepareForTest({LoginSuccessHandler.class})
#Test
public void onAuthenticationSuccess() throws Exception {
whenNew(OrcaAuthorizationServiceBeanService.class).withArguments(URL.class).thenReturn(orcaAuthorizationServiceBeanService);
p("Mocking Orca WS calls");
when(orcaAuthorizationServiceBeanService.getOrcaAuthorizationServiceBeanPort()).thenReturn(orcaAuthorizationServiceBean);
when(orcaAuthorizationServiceBean.getUserRoles(any(Header.class), anyString())).thenReturn(userRolesReturnModel);
when(userRolesReturnModel.getUserRoles()).thenReturn(Collections.singletonList("ADMIN"));
p("Starting mock log in");
loginSuccessHandler.onAuthenticationSuccess(request, response, authentication);
assertEquals(MockHttpServletResponse.SC_OK, response.getStatus());
}
private void p(String s) {
System.out.println(s);
}
And here i get null
OrcaAuthorizationServiceBeanService service = new OrcaAuthorizationServiceBeanService(new URL(url));
When i debug, i can confirm that powermockito is running to mock this object creation and this method is being called:
public static synchronized NewInvocationControl<?> putNewInstanceControl(Class<?> type, NewInvocationControl<?> control) {
return newSubstitutions.put(type, control);
}
And those are the parameters:
type = {Class#1755} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
cachedConstructor = null
newInstanceCallerCache = null
name = "com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
classLoader = {MockClassLoader#2118}
reflectionData = {SoftReference#2119}
classRedefinedCount = 0
genericInfo = null
enumConstants = null
enumConstantDirectory = null
annotationData = null
annotationType = null
classValueMap = null
control = {MockitoNewInvocationControl#2093}
substitute = {InvocationSubstitute$$EnhancerByMockitoWithCGLIB$$4d9f6379#2109} "invocationSubstitute"
CGLIB$BOUND = true
CGLIB$CALLBACK_0 = {PowerMockMethodInterceptorFilter#2115}
CGLIB$CALLBACK_1 = {SerializableNoOp#2116}
And here is the result when it hits the getter:
public static synchronized NewInvocationControl<?> getNewInstanceControl(Class<?> type) {
return newSubstitutions.get(type);
}
type = {Class#277} "class java.net.URL"
newSubstitutions = {HashMap#1823} size = 1
0 = {HashMap$Node#2195} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService" ->
key = {Class#1755} "class com.ttech.timsgui.ldap.OrcaAuthorizationServiceBeanService"
value = {MockitoNewInvocationControl#2137}
this returns null and object creation returns null too. What causes this problem?

Try,
whenNew(OrcaAuthorizationServiceBeanService.class).withAnyArguments().thenReturn(orcaAuthorizationServiceBeanService);

Related

when-then-Return functions are not working

I am writing JUnit tests for a controller class. I have tried several methods, but the when.thenReturn() is getting bypassed every time. Following is the sample code:
Controller class:
#RestController
public class FundController {
#Autowired
private FundDAO msDAO = new FundDAO();
private FundUtil msUtil = new FundUtil();
#PostMapping(value = "/v1/fund/search", produces = { MediaType.APPLICATION_JSON_VALUE })
public FundSearchResponse fundNameSearch(
#ApiParam(name = "fundName", value = "fund names in form of JSON", required = true) #RequestBody(required = true) fundName fundNameRequest,
#ApiParam(name = "limit", value = "Number of Records per page", required = false, defaultValue = "10") #RequestParam(value = "limit", required = false, defaultValue = "10") Integer limit) {
FundSearchResponse fundSearchResponse = new FundSearchResponse();
if (!msUtil.validatefundSearchRequest(fundNameRequest, limit)) {
String validationMsg = msUtil.getValidationMsg();
fundSearchResponse.setResponse(
msUtil.buildServiceResponse(Constants.CODE_400_BAD_REQUEST, Constants.TYPE_400_BAD_REQUEST,
validationMsg.isEmpty() ? Constants.DESC_400_BAD_REQUEST : validationMsg));
fundSearchResponse.setfunds(null);
fundSearchResponse.setTotalRecords(0);
}
else {
try {
fundSearchResponse = msDAO.fundNameSearch(fundNameRequest.getfundName(), limit);
if (fundSearchResponse.getfunds() != null) {
fundSearchResponse.setTotalRecords(fundSearchResponse.getfunds().size());
fundSearchResponse.setResponse(msUtil.buildServiceResponse(Constants.CODE_200_SUCCESS));
} else {
fundSearchResponse.setTotalRecords(0);
fundSearchResponse.setResponse(msUtil.buildServiceResponse(Constants.CODE_200_SUCCESS,
Constants.TYPE_200_SUCCESS, Constants.DESC_404_NOT_FOUND));
}
} catch (ApiException e) {
fundSearchResponse.setResponse(msUtil.buildServiceResponse(e.code, e.type, e.getMessage()));
fundSearchResponse.setTotalRecords(0);
}
}
return fundSearchResponse;
}
JUnit test class:
#WebMvcTest(controllers = FundController.class)
#ActiveProfiles("test")
public class FundTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private FundDAO msDAO;
private FundUtil msUtil;
private fundName fundName;
#Before
public void setUp() {
fundName = MockData.getfundName();
msUtil = new FundsOrchestratorUtil();
msDAO = new FundsOrchestratorDAO();
}
#Test
public void shouldFetchAllUsers() throws Exception {
fundsSearchResponse fundSearchResponse = MockData.getfundsSearchResponse();
when(msUtil.validatefundSearchRequest(fundName, 5)).thenReturn(true); // Problem : getting bypassed to Util class
//given(msUtil.validatefundSearchRequest(Mockito.any(fundName.class), Mockito.anyInt())).willReturn(true);
given(msDAO.fundNameSearch(Mockito.anyString(), Mockito.anyInt())).willReturn(fundSearchResponse);
this.mockMvc.perform(post("/v1/funds/search"))
.andExpect(status().isOk());
}
}
I followed this web site JUnit and Mockito, as my usual way of JUnit (#RunWith(SpringJUnit4ClassRunner.class)) were not working. Though both of these are almost same, the problem still persists. As the class call restriction using when().thenReturn() are not working. I am not good at JUnit, so I might be missing something. Please let me know how to get this done. As the dependent class is looking for the data in object which in this case is passed as Mockito.any(Classname.class). When passed with the object with data, its giving error
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
You have to create a mock first :
FundUtil fundUtilMock = org.mockito.Mockito.mock(FundUtil.class);
Then you can call :
when(fundUtilMock.validatefundSearchRequest(fundName, 5)).thenReturn(true);

var that takes value from properties file is null when actual method is called from Junit instead of value in test.properties file. How to fix?

Method for which test is writen:
public class SampleClassA {
#Value("${aws.s3.bucket}")
private String bucketName;
public Object retrieveObject(String fileUUID) {
Object repoDoc = new Object();
MetaData metaData = getMetaData(fileUUID);
repoDoc.setDocumentContent(retrieveFileFromS3(AppUtils.getKeyPath(metaData.getPath(), bucketName, fileUUID)));
return repoDoc;
}
}
AppUtils method:
public final class AppUtils {
public static String getKeyPath(String path, String bucketName, String fileUUID){
if(path.startsWith(bucketName)){
return (path.replace((bucketName+"/"), "")+"/"+fileUUID);
} else {
throw new Exception(ErrorCode.INVALID_PATH);
}
}
}
My JUnit:
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest(classes = S3DocumentManagerImpl.class)
#EnableConfigurationProperties
#ActiveProfiles("test")
public class SampleClassATest {
#Value("${aws.s3.bucket}")
private String bucketName;
String fileUUID;
#Spy
SampleClassA sampleClassA1;
#InjectMocks
SampleClassA sampleClassA;
#BeforeEach
void setUp() {
}
#Before
public void setup() {
fileUUID = "TestFileUUID";
repoObj = new Object();
metaData = new MetaData();
bucketName = "testBucket";
}
#Test
public void retrieveObjectSuccessTest() throws Exception {
metaData = CreateObjectsForEntityStub.createMetaDataModel();
doReturn(metaData).when(sampleClassA1).getMetaData(fileUUID);
when(repository.findById(fileUUID)).thenReturn(Optional.of(metaData));
//Here Bucket Name has Value form application-test.properties
doReturn(null).when(sampleClassA1).retrieveFileFromS3(AppUtils.getKeyPath(metaData.getPath(), bucketName, fileUUID));
//When called from below bucketName is null
repoObj = sampleClassA.retrieveObject(fileUUID);
assertEquals(repoObj.getRepositoryDocumentId(), fileUUID);
}
}
When called from Mockito the value for bucketName exists and is picked from my applications-test.properties whereas when the actual method is called from the test the bucketName is null. Which causes my test to fail with a null pointer exception when it reaches AppUtils.getKeyPath(). How to fix this unit test?

Mock returns Wrong Collection

I want to return a filled Map with my mocked Object, but the size of the Map is always Null. The mocked Object "CommandLineValues options" is not Null and also the Boolean variable "doCleanFirst" I can mock successfully.
Here is my Testclass:
#RunWith(MockitoJUnitRunner.class)
public class IndexBMECatTest {
#InjectMocks
private IndexBMECat classUnderTest;
#Mock
private CommandLineValues options;
#Test
public void testAccessoryItemHasNoDublicates() {
Map<String, String> testMap = new HashMap<>();
testMap.put("key", "value");
when(options.getCleanFirst()).thenReturn(false);
when(options.readWhitlist()).thenReturn(testMap);
classUnderTest.run();
}
}
Here is the constructor of my class where the code start, the tested Method is not relevant:
private boolean doCleanFirst;
private Map<String, String> whiteList;
public IndexBMECat(TransportClient client, CommandLineValues options, BMECatReader reader) throws Exception {
this.doCleanFirst = options.getCleanFirst();
this.whiteList = options.readWhitlist();
if (whiteList.isEmpty()) {
throw new Exception("Missing whiteList");
}
}
I also tried other variants:
Mock the Map and the return value of the method "isEmpty"
Initialize the Testclass and give the mocked Object to the constructor
But the whiteList has always the size = 0
Thx, this works now:
private IndexBMECat classUnderTest;
#Mock
private CommandLineValues options;
#Mock
private BMECatReader reader;
#Mock
TransportClient client;
#Before
public void setUp() throws Exception {
Map<String, String> testMap = new HashMap<>();
testMap.put("key", "value");
when(options.getCleanFirst()).thenReturn(false);
when(options.readWhitlist()).thenReturn(testMap);
classUnderTest = new IndexBMECat(client, options, reader);
}
#Test
public void testAccessoryItemHasNoDublicates() {
classUnderTest.run();
}
First I mock the methods which will be executed in the contructor and then I create the instance of my testclass.

Mock method return type in java

Below is main code consist of one util class and service class using it
#PropertySource("classpath:atlas-application.properties")
public class ApacheAtlasUtils {
#Value("${atlas.rest.address}")
private String atlasURL;
#Value("${atlas.rest.user}")
private String atlasUsername;
#Value("${atlas.rest.password}")
private String atlasPassword;
private AtlasClientV2 client;
public AtlasClientV2 createClient() {
if (client == null) {
return new AtlasClientV2(new String[] {atlasURL}, new String[] {atlasUsername, atlasPassword});
} else {
return client;
}
}
}
Service Class is below :-
#Override
public Page<SearchResultDto> findFilesWithPages(QueryParent queryParent, Pageable pageable)
throws AtlasServiceException {
// Some code
client = new ApacheAtlasUtils().createClient();
//some code
}
I am writing unit test for service method and I am getting exception for createClient method asking for values for url, username and password which should not happen as this should be mocked but the mocking is giving me below error
java.lang.IllegalArgumentException: Base URL cannot be null or empty.
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:141)
at org.apache.atlas.AtlasServerEnsemble.<init>(AtlasServerEnsemble.java:35)
at org.apache.atlas.AtlasBaseClient.determineActiveServiceURL(AtlasBaseClient.java:318)
at org.apache.atlas.AtlasBaseClient.initializeState(AtlasBaseClient.java:460)
at org.apache.atlas.AtlasBaseClient.initializeState(AtlasBaseClient.java:448)
at org.apache.atlas.AtlasBaseClient.<init>(AtlasBaseClient.java:132)
at org.apache.atlas.AtlasClientV2.<init>(AtlasClientV2.java:82)
at com.jlr.stratus.commons.utils.ApacheAtlasUtils.createClient(ApacheAtlasUtils.java:40)
at com.jlr.stratus.rest.service.impl.FileSearchService.findFilesWithPages(FileSearchService.java:49)
The Test code is as follows:-
private FileSearchService fileSearchService;
#Spy
private ApacheAtlasUtils apacheAtlasUtils;
#Mock
private AtlasClientV2 client;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
fileSearchService = new FileSearchService();
}
#Test
public void findFilesWithPages_searchAll() throws AtlasServiceException {
Mockito.doReturn(client).when(apacheAtlasUtils).createClient();
service.search(queryParent,pageable);
}
Your idea with spying is adequate (you can even go for mocking if you do not actually need any true implementation of that class).
The problem lies in the implementation:
// Some code
client = new ApacheAtlasUtils().createClient();
//some code
}
Instead of having the ApacheAtlasUtils as an instance variable (or a supplier method) you create the instance on the fly.
Mockito is not smart enough to catch that operation and replace the real object with you spy.
With the supplier method you can set up your test as follows:
#Spy
private FileSearchService fileSearchService = new FileSearchService();
#Spy
private ApacheAtlasUtils apacheAtlasUtils = new ApacheAtlasUtils();
#Mock
private AtlasClientV2 client;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
doReturn(apacheAtlasUtils).when(fileSearchService).getApacheUtils();
}
in your SUT:
#Override
public Page<SearchResultDto> findFilesWithPages(QueryParent queryParent, Pageable pageable)
throws AtlasServiceException {
// Some code
client = getApacheUtils().createClient();
//some code
}
ApacheAtlasUtils getApacheUtils(){
return new ApacheAtlasUtils();
}

Java Reference incorrect

i'm using OWL-S API (source and javadoc here: http://on.cs.unibas.ch/owls-api/apidocs/ )
If i do this i have the correct result:
public class Example {
private static ISWRLFactory factory; //is a interface
private string url = "http://...";
private Service aService;
private OWLOntology ont;
void method_A(){
URI aURI = URI.create(url);
OWLKnowledgeBase aKB = OWLFactory.createKB();
aService = aKB.readService(aURI);
ont = aKB.createOntology(aURI);
ont.createService(aService.getURI());
}
void method_B(){
factory = SWRLFactory.createFactory(ont);
Atom builtAtom = factory.createNotEqual(x, variab); //x and variab are two variable
}
}
But if i do this i don't have the correct result:
public class Example {
private static ISWRLFactory factory; //is a interface
private string url = "http://...";
private Service aService;
private OWLOntology ont;
void method_A(){
URI aURI = URI.create(url);
OWLKnowledgeBase aKB = OWLFactory.createKB();
aService = aKB.readService(aURI);
ont = aKB.createOntology(aURI);
ont.createService(aService.getURI());
factory = SWRLFactory.createFactory(ont);
}
void method_B(){
Atom builtAtom = factory.createNotEqual(x, variab); //x and variab are two variable
}
}
Why?
Difference exist in executing " factory = SWRLFactory.createFactory(ont);" line in method_A() and method_B().
Are you sure 'factory' object is not modified between method_A() and method_B() calls? Does 'x' and 'variable' have some dependency on 'factory' ?

Categories