Checkout our demo site to practice selenium https://magento.softwaretestingboard.com/

0 like 0 dislike
2.0k views
by Contributing Tester (60 points)
edited by

I hope you could give me some testing guidance.

I have a static method that passes the iFile interface reference and a dir String reference into a class called FileUtils

public static List<String> recursive(IFile thisFile, String thisDir);

I wrote a wrapper class and method to call the static method and refactored the code to call the non-static method, as I believe Mockito does not mock static nor final classes:

public class FileUtilsWrapper{

/**

* Wrapper for Mockito

* @param file

* @param dir

* @return

*/

public LinkedList<String> getRecursive(IFile file, String dir){

    return FileUtils.recursive (file, dir);

}

}

I then created the mock:

import com.mockery.FileUtilsWrapper;

@Mock private FileUtilsWrapper fuw;

further down I instantiate the mock:

fuw = mock(FileUtilsWrapper.class);

List<String> mockList = new LinkedList<>();

mockList.add(dir.concat("/home/news/2018/04/astronomers-bright-explosions.html"));

mockList.add(dir.concat("/home/news/2018/04/blackveined-butterfly-return.htlml"));

when(fuw.getRecursive(file, dir)).thenReturn(mockList);

I expect the test to now provide the mockList back rather than entering into the recursive static method.  However, that does not happen, what does happen is that the test proceeds into the static method and then throws a nullpointer exception in a call inside that static method.

I tried various things, like changing the mock into a spy, and leaving the when statement the same. I tried also to run thenCallRealMethod which did not work. Can you maybe give me some pointer to how to approach this test?

2 Answers

1 like 0 dislike
by Contributing Tester (60 points)
selected by
 
Best answer

Here is how I got the test passing the static method:

@RunWith(PowerMockRunner.class)

@PowerMockRunnerDelegate(Cucumber.class)

@PowerMockIgnore( { "javax.management.*" })

@PrepareForTest({FileUtils.class})

@CucumberOptions(       

  plugin {"pretty""html:target/build/reports/tests/test""junit:/Users/arnout/dev/buildserver.git/build/test-results/test/cucumber.xml""json:/Users/arnout/dev/buildserver.git/build/test-results/test/cucumber.json”},

  dryRun = false,

  strict = false,

  features = {"/Users/arnout/dev/buildserver.git/soton-test/resources/features"},

  snippets = SnippetType.CAMELCASE

)

public class RelatedNewsFeatureTest { }

 I have then created a Helper class that does all the digging into the implementation classes.

The helper class has this instance field:

mockStatic(FileUtils.class);

Then I run 

when(FileUtils.recursiveFileList(customFileDaldirPath)).thenReturn(mockPageList);

I use Gradle for dependencies. Here is the list I got:

testCompile group'org.mockito'name'mockito-all'version'1.10.19'

testCompile group: 'org.powermock'name'powermock-core'version'1.7.4'

testCompile group'org.powermock'name'powermock-module-junit4'version'1.7.4'

testCompile group'org.powermock'name'powermock-api-mockito'version'1.7.4'

testCompile group'org.powermock'name'powermock-module-junit4-rule'version'1.7.4'

testCompile group'org.powermock'name'powermock-classloading-base'version'1.7.4'

testCompile group'org.powermock'name'powermock-classloading-objenesis'version'1.7.4'

by Master (1.2k points)
thank you for posting your solution.
0 like 0 dislike
by Master (1.2k points)

That is expected. Because, the FileUtilsWrapper  class  is under the java.lang.Object package.

So, if you are creating wrapper class, you can try writing the class with the package name.

E.g.

@Mock private your.package.FileUtilsWrapper fuw;

fuw = mock(your.package.FileUtilsWrapper.class);

by Contributing Tester (60 points)
edited by

I import the package with an import statement, sorry I was not clear enough. The test class has

import uk.ac.soton.livesite.utils.FileUtilsWrapper;
by Master (1.2k points)
Okay

when(fuw.getRecursive(file, dir)).thenReturn(mockPageList)

On the above line, shouldn't it return mockList?
by Contributing Tester (60 points)
moved by

yes, correct. that was a typo. I am amending the real code for this conversation and did not see that. Sorry

when(fuw.getRecursive(file, dir)).thenReturn(mockList).

by Master (1.2k points)
Okay,
You are mocking a method with parameters.

Try this.

when(fuw.getRecursive(any(IFile.class), any(String.class))).thenReturn(mockPageList);
by Contributing Tester (60 points)
moved by
I just tried with any argument matchers, I still get passed to the actual static method through the Wrapper class.
by Master (1.2k points)
can you post your complete test class?
by Contributing Tester (60 points)
edited by

I managed to get Powermock to work with the Cucumber test. I have now managed to get through the code and now have now got a failure with the Cucumber step which is odd.

I have a Hamcrest Path matcher that works fine in Junit4 and Junit 5 tests I have created for other features. For example this Junit5 test:

@Test
@DisplayName("Given the DCR path does not exist, result is the corresponding DCR excluded from result")
void givenDCRPathDoesNotExistResultExcludesDCR() throws Exception {
    mockQuery(falsePage, falseDCR);
    String falseResult = generator.generateUGProgrammeXML(fm, stmt).getRootElement().asXML();
    assertThat(parse(falseResult), not(hasXPath("/Programmes/Programme/Name",
            equalTo("F400 BSc Archaeology"))));
}

This same matcher does not work when I run it through Cucumber in the step:

When("^(\\S+) has (\\d+) articles subscribed$", (String feed, Integer count) -> LOG.info("scenario 3 --- number of articles subscribed to feed " + feed + " is " + count));

Then("^(\\d+) pages should show on the (\\S+\\.page) in the related news widget$", (Integer outcome, String currentPage) -> {
    LOG.info("scenario 3 --- " + outcome + " pages should show on the  " + currentPage);
    assertThat(parse(xml), hasXPath("/Collection/Root/Group/NewsRelease", equalTo(outcome.toString())));
});

The result of the Cucumber-style assertThat is:

java.lang.AssertionError: 

Expected: an XML document with XPath Collection 

     but: was <[#document: null]>  at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8) at uk.ac.soton.livesite.cucumber.RelatedNewsSteps.lambda$new$1(RelatedNewsSteps.java:48) at ✽.Then 3 pages should show on the /news/2018/04/key-area-of-immune-cell.page in the related news widget(creating-news-articles/related_news.feature:14)

When I run the IntelliJ debugger, I can see that parse(xml) returns a Document object with 2141 elements in it, so there is something not right here. 

by Master (1.2k points)
I am glad that your problem is solved, can you share the solution that you have got? Also, the above issue related to Cucumber is a new issue. Can you start a new thread by posting it as a new question?


This site is for software testing professionals, where you can ask all your questions and get answers from 1300+ masters of the profession. Click here to submit yours now!

...