NoSuchField error in java code but field exists - java

I have the following code.
public class Table {
Integer[] data;
public Table() {
this.data = new Integer[100];
}
public boolean insert(int key){
data[53] = 1;
return true;
}
}
&&
public class test{
private Table tab;
protected void setUp() throws Exception {
tab = new Table();
}
public void testInsertTable() {
tab.insert(1);
assertTrue(tab.data[53] == 1); // error here
}
}
The test class is run using JUnit.
The code works when i run in it Eclipse but i get a NoSuchField error on the line pointed by the comment when i run it outside of Eclipse.
The class responsible for the problem is Table, that much i know for certain.

What could be wrong is you are not using #Before annotation on the setup method
The correct code should be
public class test{
private Table tab;
#Before
protected void setUp() throws Exception {
tab = new Table();
}
#Test
public void testInsertTable() {
tab.insert(1);
assertTrue(tab.data[53] == 1); // error here
}
}

Related

Testing for class field with is share among methods

I have a Java class as follow
public class MyClass {
private final ShowFactory showFactory;
private SomeShow someShow;
public MyClass(ShowFactory showFactory) {
this.showFactory = showFactory;
startShow();
}
public void startShow() {
someShow = showFactory.createShow();
someShow.start();
}
public void showSomething() {
MagicBox magicBox = new MagicBox();
someShow.showSomething(magicBox);
}
public void stopShow() {
someShow.stop();
}
}
and trying to test showSomething method. Complete test file is as follow
public class MyClassTest {
private ShowFactory showFactory;
private SomeShow someShow;
#Before
public void setUp() {
showFactory = mock(ShowFactory.class);
someShow = mock(SomeShow.class);
when(showFactory.createShow()).thenReturn(someShow);
}
#Test
public void shouldStartShow() {
new MyClass(showFactory);
verify(someShow).start();
}
#Test
public void shouldShowSomething() throws Exception {
MagicBox magicBox = mock(MagicBox.class);
PowerMockito.whenNew(MagicBox.class).withAnyArguments().thenReturn(magicBox);
doNothing().when(someShow).showSomething(magicBox);
InOrder inOrder = inOrder(someShow);
MyClass myClass = new MyClass(showFactory);
myClass.showSomething();
inOrder.verify(someShow).start();
inOrder.verify(someShow).showSomething(magicBox);
}
#Test
public void shouldStopShow() {
MyClass myClass = new MyClass(showFactory);
myClass.stopShow();
verify(someShow).start();
verify(someShow).stop();
}
}
But test shouldShowSomething is failing with error Wanted but not invoked. Any thing I am missing here? Any suggestion?
It was simple fix. After reading through https://github.com/powermock/powermock/wiki/MockConstructor#quick-summary (thanks to #roby) turns out I was missing the #PrepareForTest annotation for the class.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class MyClassTest {
...
}

How to append data-provider name along with method name in Extent Report?

I am working on Extent Report framework in my current project. In my test class I am using Data-provider class to import the test data. The particular test contains 10 validation test iterating the data-provider key.
When it comes to Extent report I am writing the method name into the report
But I have to differentiate each data-provider test with a name matching to each validation test.
Here are my script :1. Extent Report Config:
#BeforeSuite
public void setUp()
{
htmlReporter = new ExtentHtmlReporter(System.getProperty("user.dir") +"/test-output/extentReport.html");
extent = new ExtentReports();
extent.attachReporter(htmlReporter);
extent.setSystemInfo("OS", "Windows");
extent.setSystemInfo("Host Name", "1016086");
extent.setSystemInfo("Environment", "QA");
extent.setSystemInfo("User Name", "BABURAJ V D");
htmlReporter.config().setChartVisibilityOnOpen(true);
htmlReporter.config().setDocumentTitle("Extent report");
htmlReporter.config().setReportName("Final Report");
}
#BeforeClass
public synchronized void beforeClass() {
test = extent.createTest(getClass().getSimpleName());
parentTest.set(test);
}
#BeforeMethod
public synchronized void beforeMethod(Method method) {
child = parentTest.get().createNode(method.getName());
childTest.set(child);
}
#AfterMethod
public synchronized void afterMethod(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE)
childTest.get().fail(result.getThrowable());
else if (result.getStatus() == ITestResult.SKIP)
childTest.get().skip(result.getThrowable());
else
childTest.get().pass("Test passed");
}
#AfterSuite
public void tearDown(){
extent.flush();
}
#Test(priority = 2, dataProvider = GE_XR240_DEVICE_DataProvider.DEVICE_ADD_VALIDATIONS, dataProviderClass = GE_XR240_DEVICE_DataProvider.class)
public void OPTIMA_XR240_FAILED_MESSAGE_VALIDATION(Map<String, String> deviceTestData) throws InterruptedException { }
These are the validations happening in that particular test OPTIMA_XR240_FAILED_MESSAGE_VALIDATION or the error message which should be displayed in the UI:
Add Device Failed - System name should be filled
Add Device Failed - System Id should be filled
Add Device Failed - Manufacturer should be assigned
Add Device Failed - System model should be assigned
Add Device Failed - Current IP Address / Host Name should be filled
So that I have make the report which should contain a piece of information relates to the validation it performs , instead of just the method name.
It is creating node with method name as you have define method called "OPTIMA_XR240_FAILED_MESSAGE_VALIDATION"
If you wants to get Customize name, You may pass it like:
child = parentTest.get().createNode("Test node");
childTest.set(child);
Everytime if you wants to give some numeric identification like "Test node 1", "Test node 2" and so on. You may get it by Count increment or loop and so it define like:
child = parentTest.get().createNode("Test node" +i);
childTest.set(child);
You can increment i value before method can get complete.
This is the pre-release snippet from extent-testng-plugin which will be released soon as part of version 4, but posting it here as this is how you will get the data-provider into your methods:
public class ExtentITestListener
implements ITestListener {
private static final ExtentReports EXTENT = Extent.getInstance();
private static ThreadLocal<ExtentTest> methodTest = new ThreadLocal<ExtentTest>();
private static ThreadLocal<ExtentTest> dataProviderTest = new ThreadLocal<>();
#Override
public synchronized void onStart(ITestContext context) { }
#Override
public synchronized void onFinish(ITestContext context) {
EXTENT.flush();
}
#Override
public synchronized void onTestStart(ITestResult result) {
String methodName = result.getMethod().getMethodName();
if (result.getParameters().length>0) {
if (methodTest.get() != null && methodTest.get().getModel().getName().equals(methodName)) { }
else {
createTest(result);
}
String paramName = Arrays.asList(result.getParameters()).toString();
ExtentTest paramTest = methodTest.get().createNode(paramName);
dataProviderTest.set(paramTest);
} else {
createTest(result);
}
}
private void createTest(ITestResult result) {
String methodName = result.getMethod().getMethodName();
ExtentTest test = EXTENT.createTest(methodName);
methodTest.set(test);
String[] groups = result.getMethod().getGroups();
if (groups.length > 0) {
Arrays.asList(groups)
.forEach(x -> methodTest.get().assignCategory(x));
}
}
#Override
public synchronized void onTestSuccess(ITestResult result) {
getTest(result).pass("Test passed");
}
private ExtentTest getTest(ITestResult result) {
ExtentTest t = result.getParameters() != null && result.getParameters().length>0
? dataProviderTest.get()
: methodTest.get();
return t;
}
#Override
public synchronized void onTestFailure(ITestResult result) {
getTest(result).fail(result.getThrowable());
}
#Override
public synchronized void onTestSkipped(ITestResult result) {
getTest(result).skip(result.getThrowable());
}
#Override
public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult result) { }
}
public class Extent
implements Serializable {
private static final long serialVersionUID = 1L;
private static class ExtentReportsLoader {
private static final ExtentReports INSTANCE = new ExtentReports();
static {
}
}
public static synchronized ExtentReports getInstance() {
return ExtentReportsLoader.INSTANCE;
}
#SuppressWarnings("unused")
private ExtentReports readResolve() {
return ExtentReportsLoader.INSTANCE;
}
}
Since this is a ITestListener, you can add it directly to your test or base class like so:
#Listeners(ExtentITestListenerAdapter.class)
public class MyTests {
#Test
public void test() {
...
}
}
I found the solution for the above question which works fine for me. Put the below code inside your methods in listener class it can fetch the parameter from your test method
StringBuilder testName = new StringBuilder(result.getMethod().getMethodName());
Object[] parameters = result.getParameters();
if (parameters.length > 0)
{
StringBuilder p = new StringBuilder();
for (int i = 0; i < parameters.length; i++)
{
//pass the parameter location which you want to add as a testname
if(i == 4)
{
p.append(Utils.toString(parameters[i]));
}
}
}
test = extent.createTest(testName.toString());

ThreadWeaver always throws IllegalArgumentException

I am trying to use Google ThreadWeaver to write a unit test for concurrent code. No matter what I do, I will get an IllegalArgumentException. I am still working with an example, but even that does not work. This is what I tried:
public class ExampleTest {
public static class ExampleMain implements MainRunnable<Example> {
private Example example;
#Override
public Class<Example> getClassUnderTest() {
return Example.class;
}
#Override
public String getMethodName() {
return null;
}
#Override
public Method getMethod() throws NoSuchMethodException {
return null;
}
#Override
public void initialize() throws Exception {
example = new Example();
}
#Override
public Example getMainObject() {
return example;
}
#Override
public void terminate() throws Exception {
}
#Override
public void run() throws Exception {
example.test("second");
}
}
public static class ExampleSecondary implements SecondaryRunnable<Example, ExampleMain> {
private ExampleMain exampleMain;
#Override
public void initialize(ExampleMain main) throws Exception {
exampleMain = main;
}
#Override
public void terminate() throws Exception {
}
#Override
public boolean canBlock() {
return false;
}
#Override
public void run() throws Exception {
exampleMain.getMainObject().test("main");
}
}
public static class Example {
private List<String> list = new ArrayList<String>();
public String test(String s) {
System.out.println("1" + s);
list.add(s);
System.out.println("2" + s);
return list.get(0);
}
}
#Test
public void testThreadWeaver() throws Exception {
ClassInstrumentation instrumentation = Instrumentation.getClassInstrumentation(Example.class);
Method tested = Example.class.getDeclaredMethod("test", String.class);
Method breakpoint = List.class.getDeclaredMethod("add", Object.class);
CodePosition codePosition = instrumentation.afterCall(tested, breakpoint);
InterleavedRunner.interleave(new ExampleMain(), new ExampleSecondary(), Arrays.asList(codePosition)).throwExceptionsIfAny();
}
}
The stack trace says:
java.lang.IllegalArgumentException: Class Example is not instrumented
at
com.google.testing.threadtester.CallLoggerFactory.getClassInstrumentation(CallLoggerFactory.java:108)
at
com.google.testing.threadtester.Instrumentation.getClassInstrumentation(Instrumentation.java:65)
at MyTest.testThreadWeaver(MyTest.java:92
I followed the instructions at the official Google code webpage, but it does not seem to work. Any ideas?
ThreadWeaver needs to instrument your classes in order to add breakpoints to your methods. Therefore, you cannot run the tests with JUnit directly but you must run your test from a specific test runner. For your case this would be ThreadedTestRunner. The actual test methods must then be annotated with #ThreadedTest instead of #Test. This should work:
#Test
public void startTest() throws Exception {
new ThreadedTestRunner().runTests(getClass(), Example.class);
}
#ThreadedTest
public void testThreadWeaver() throws Exception {
// here comes your test
}

Function works in main class but not it test class

I have a class which compiles and runs as expected (adds one test node per execution):
public class ReqsDb {
private final String STORE_DIR;
public GraphDatabaseService graphDb;
private static enum RelTypes implements RelationshipType {
IDENTIFIES, SATIFIES
}
public ReqsDb(String dbPath) {
STORE_DIR = dbPath;
graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(STORE_DIR);
registerShutdownHook(graphDb);
}
public void createTestNode() {
Transaction tx = graphDb.beginTx();
Node newNode;
try {
newNode = graphDb.createNode();
newNode.setProperty("test", "test");
tx.success();
} finally {
tx.finish();
}
}
private static void registerShutdownHook(final GraphDatabaseService graphDb) {
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
graphDb.shutdown();
}
});
}
void shutDown() {
graphDb.shutdown();
}
public static void main(String[] args) {
ReqsDb testDb = new ReqsDb("target/testDb");
testDb.createTestNode();
}
}
However the test function, testCreateTestNode() causes error:
java.lang.RuntimeException: org.neo4j.kernel.lifecycle.LifecycleException: Component 'org.neo4j.kernel.StoreLockerLifecycleAdapter#4e3a2be1' was successfully initialized, but failed to start.
Since the function works as called from main(), I think there is something wrong with the test class.
package com.github.dprentiss;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
public class ReqsDbTest extends TestCase {
protected ReqsDb testDb = new ReqsDb("target/testDb");
public ReqsDbTest(String testName) {
super(testName);
}
public static Test suite() {
return new TestSuite(ReqsDbTest.class);
}
public void testDbService() {
assertNotNull(testDb);
}
public void testCreateTestNode() {
testDb.createTestNode();
}
public void tearDown() {
testDb.shutDown();
}
Is there something wrong with my test set up?
Try to put
protected ReqsDb testDb = new ReqsDb("target/testDb");
in an init method . Follow this example:
Is there a basic template I can use to create a test?

Truncate the method in java

I have the following code:
public class Search {
private Desktop desktop = new Desktop();
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
baseState.execute(desktop);
}
#Test
public void searchNames() {
desktop.<BrowserApplication>find("//BrowserApplication").<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
}
}
I was able to truncate the Test method to this:
public class Search {
private Desktop desktop = new Desktop();
BrowserApplication app;
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
app = baseState.execute(desktop);
}
#Test
public void searchNames() {
app.<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
}
How do I truncate the method even further? I would like to be able to use something like this:
win.<DomButton>find("//INPUT[#id='edit-submit']").select();
instead of this chunky long:
desktop.<BrowserApplication>find("//BrowserApplication").<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
Please paste the whole class in your response?
public class Search {
private Desktop desktop = new Desktop();
BrowserWindow win;
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
win = baseState.execute(desktop).find("//BrowserWindow");
}
#Test
public void searchNames() {
win.<DomButton>find("//INPUT[#id='edit-submit']").select();
}
}

Categories