I don't have the newest version of TestNG, and I have option to add #Test on constructor, java docs
#Target({METHOD, TYPE, CONSTRUCTOR})
public #interface Test {
I didn't find any clue on usage in docs or searching online
#Test Marks a class or a method as part of the test.
When/Why #Test can be define on constructor? is it for internal purposes only?
I saw that CONSTRUCTOR was removed in latest TestNG version, but I didn't find why.
See issue "Remove irrelevant "targets" for TestNG annotations": The target CONSTRUCTOR had no functionality in older versions, because constructors were not seen as test methods. That's why the target was removed later.
Related
I use JUnit 5 and I have a simple abstract class that serves as a test provider for its child classes:
abstract class TestProvider {
#TempDir
#SuppressWarnings("unused")
Path tempDir;
protected void helpWithSomething() {
// let's pretend it actually does something
}
}
SonarQube complains because of the RSPEC-2924 rule that states the following:
This rule also applies to the JUnit 5 equivalent classes: TempDir, and TestInfo.
Surprisingly, the page offers a solution without any creation of such temporary folder, either using #Rule with older versions of JUnit or with #TempDir as of JUnit 5. Note the following snippet only removed non-compliant line with no alternative and compliant solution, which is kind of ridiculous.
public class ProjectDefinitionTest {
#Test
public void shouldSetKey() {
ProjectDefinition def = ProjectDefinition.create();
def.setKey("mykey");
assertThat(def.getKey(), is("mykey"));
}
}
I would expect at least a relevant compliant solution as this completely breaks the gist of the test. Note the tempDir is actually accessed with the child classes.
What is a correct and compliant usage of #TempDir according to SonarQube? Although I am aware of using a different suppression (#SuppressWarnings("squid:S2924")), I would like to know a compliant solution.
I have upgraded from testng 6.3.1 to 6.14.2 and after this I am getting error on org.testng.annotations.Configuration as the class does not exist.
I just want to know how to replace this?.I have checked the deprecated API and found that this is deprecated in 6.9.x.
Thanks
TLDR; Use the dedicated annotations instead, eg: #BeforeTest instead of #Configuration(beforeTest = true).
TBH I never used it, I've always used the dedicated #BeforeTest, #AfterTest, etc annotations, but out of curiosity I've done a bit of research:
according to the change log (currently line 1129) it's been deprecated since v 5.0 of 2009/04/01: Added: Deprecated #Configuration and introduced #BeforeSuite/Test/Class/TestMethod
it's been removed with this commit
before its removal (up to v6.11) it's javadoc read:
Configuration information for a TestNG class.
Deprecated.
Use #BeforeSuite, #AfterSuite, #BeforeTest, #AfterTest, #BeforeGroups, #AfterGroups, #BeforeClass, #AfterClass, #BeforeMethod, #AfterMethod
usage samples:
#Configuration(beforeTest = true)
public void setUp() {
...
In conclusion, just use the newer individual annotations instead.
I am starting to write WebDriver tests in Java having previously used C#/NUnit. I notice in any examples I have seen there is no Java version of the C# NUnit annotation for [TestFixture]. Is there such a thing in Java?
There is no equivalent annotation to [TestFixture] in JUnit. Classes with methods marked with #Test get run by most JUnit test runners without any other special markings; and #Before methods act like [SetUp]; and #After methods act like [TearDown].
I have a Gradle based Java project were I now want to mock a private method using PowerMock. The problem is that I am not able to use the PowerMockRunner as I always get the following exception when I add the #RunWith(org.powermock.modules.junit4.PowerMockRunner.class) annotation.
Error:
org.powermock.reflect.exceptions.FieldNotFoundException: Field 'fTestClass' was not found in class org.junit.internal.runners.MethodValidator.
at org.powermock.reflect.internal.WhiteboxImpl.getInternalState(WhiteboxImpl.java:581)
at org.powermock.reflect.Whitebox.getInternalState(Whitebox.java:308)
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validate TestMethods(PowerMockJUnit4MethodValidator.java:79)
at org.powermock.modules.junit4.internal.impl.testcaseworkaround.PowerMockJUnit4MethodValidator.validate InstanceMethods(PowerMockJUnit4MethodValidator.java:49)
at org.junit.internal.runners.MethodValidator.validateMethodsForDefaultRunner(MethodValidator.java:51)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.validate(PowerMockJUnit44RunnerDelegateImpl.java:108)
...
This are my test dependencies:
testCompile 'junit:junit:4.+',
'org.powermock:powermock-core:1.5.6',
'org.powermock:powermock-module-junit4:1.5.6',
'org.powermock:powermock-api-mockito:1.5.6'
The test itself fails also when completely empty (initialization error):
#RunWith(PowerMockRunner.class)
public class SomeTest {
#Test
public void testSomething() {
}
}
Any ideas what might be wrong? Other tests using PowerMock are working fine (none of them uses the PowerMockRunner).
Greetings and thanks for any help!
Ben
This is a bug that occurs when you use JUnit 4.12 and PowerMock < 1.6.1. The problem is solved in PowerMock 1.6.1. Please update your dependencies accordingly
testCompile 'junit:junit:4.12',
'org.powermock:powermock-core:1.6.1',
'org.powermock:powermock-module-junit4:1.6.1',
'org.powermock:powermock-api-mockito:1.6.1'
If you cannot upgrade PowerMock then you can use JUnit 4.11.
testCompile 'junit:junit:4.11',
'org.powermock:powermock-core:1.5.6',
'org.powermock:powermock-module-junit4:1.5.6',
'org.powermock:powermock-api-mockito:1.5.6'
Could you please add further lines of the stacktrace, which uncover more details about the problem.
There has been a bug logged against PowerMock: https://code.google.com/p/powermock/issues/detail?id=531
It appears that JUnit changed some of its internal field names that PowerMock was accessing via reflection, thus breaking the ability for PowerMock to properly inject itself.
Check what Stefan said, and above that you also need to add
#PrepareForTest({<The class/es you are Mocking>, ...})
without the prepare for test, PowerMockRunner won't know which class is mocked.
There may also exist dependencies on classpath that override a JUnit specific class which contains JUnit's version. This leads to incorrect version comparison results in PowerMock. For instance, I had com.google.android.tools:dx:1.7 on classpath (came from hunspell library). It overrides following method return result:
junit.runner.Version.id() => "3.8.1"
Usually it should return something like "4.12" or "4.11" etc.
Hi I need to write Junit tests for an Android project but it has JNI methods as it uses webkit.Is there any way I can test those android methods(I dont want to test JNI methods).
Its like:
public void androidMethod(){
//some android code
nativeInit(); //how do I mock such methods?
//some code again
}
I have tried powermock,easymock,roboelectric but wasnt successful.Please help me.
I yesterday found I could solve this with Mockito (I didn't try powermock or easymock). Assuming your class is class C, my solution is:
C c=spy(new C);
doNothing().when(c).nativeInit();
c.androidMethod()
verify(c).nativeInit();
This does, of course, require that nativeInit is visible to the test.
Similar Problem
I had the same problem event though I was already using mockito in JUnit tests under src/test. Once I added tests under src/androidTest I started having issues, including this crash:
Mockito cannot mock/spy because :
- final class
And after making the class open, manually, I still got crashes in the JNI layer as it tried to load the *.so library (which wouldn't happen if mocks were working properly).
Working Solution
Instead, what I had to do was open the class for testing purposes using Kotlin's all-open plugin. The process is also explained well in this recent medium post but it boils down to the following four simple changes that are also modeled in one of the architecture components sample apps:
1. Make these additions to build.gradle:
buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-allopen:${versions.kotlin}"
}
}
apply plugin: "kotlin-allopen"
allOpen {
// marker for classes that we want to be able to extend in debug builds
annotation 'com.your.package.name.OpenClass'
}
2. Add the corresponding annotations in the debug flavor. For example: app/src/debug/java/com/your/package/name/OpenForTesting.kt
package com.your.package.name
#Target(AnnotationTarget.ANNOTATION_CLASS)
annotation class OpenClass
#OpenClass
#Target(AnnotationTarget.CLASS)
annotation class OpenForTesting
3. Add the corresponding annotation in the release flavor. For example: app/src/release/java/com/your/package/name/OpenForTesting.kt
package com.your.package.name
#Target(AnnotationTarget.CLASS)
annotation class OpenForTesting
4. Add the #OpenForTesting annotation to the class that needs to be mocked
package com.your.package.name
#OpenForTesting
class JniClassOfVictory {
...
external fun nativeInit()
...
companion object {
init {
System.loadLibrary("victoryeveryday")
}
}
}
The result is a flexible way to mark classes as open without actually making them open in release builds. Of course, this is because the #OpenForTesting annotation that we created in release is not marked with #OpenClass but the same annotation in debug is marked with #OpenClass. In build.gradle we designated that annotation as the signal to the kotlin-allopen plugin. So any class annotated with #OpenForTesting will be made open at compile-time but only on Debug builds.