I am facing issue to get the System.getProperty("name") value per method vise after mocking System.class
Example:
#Test
public void Test1()throws Exception {
PowerMockito.mockStatic(System.class);
// Configuration
when(System.getProperty("os.name")).thenReturn("Win");
}
#Test
public void Test2() throws Exception {
PowerMockito.mockStatic(System.class);
when(System.getProperty("os.name")).thenReturn("Linux");
}
We have two tests method as mentioned above when we are running both the method independently then we are getting correct value of System.getProperty("os.name"). But when we are running class (will execute both method in class) then we are getting first method's System.getProperty("os.name") value in second method.
Please suggest.
Thank in advance.
I would use an extra external library, similar to System Rules.
You can then achieve your goal by doing the following:
public class SystemRulesTest {
#Rule
public final RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
#Test
public void test1() {
System.setProperty("os.name", "Win");
}
#Test
public void test2() {
System.setProperty("os.name", "Linux");
}
}
Note: System Rules requires Junit 4.9 or above to work.
If you want to change the system property, why not just System.setProperty("os.name", "")? This works:
public class SystemPropertyTest {
#Test
public void testWin() {
System.setProperty("os.name", "Win");
Assert.assertEquals("Win", System.getProperty("os.name"));
}
#Test
public void testLinux() {
System.setProperty("os.name", "Linux");
Assert.assertEquals("Linux", System.getProperty("os.name"));
}
}
Related
I'm writing an application test with Junit5 and TestFX.
My intention is that the main test class relaunches the application after each test. As far as I know, I shall use the annotation #BeforeEach, and it didn't work for me.
Here is my test class:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MainTest extends ApplicationTest implements FxRobotInterface {
Logger loggerGuiTesting = LoggerManager.getInstance().getLogger(LoggerType.GUI_TESTING);
#BeforeEach
#Override
public void start(final Stage stage) {
StartMain.getInstance();
this.loggerGuiTesting.log(Level.INFO, "Application starts!");
}
#AfterAll
public void endApplication() {
new ExitGuiTest().run(); // That's my internal test framework
}
#Test
public void atestIfOpeningScreenIsThere() {
verifyThat("#imageViewSplashScreenLogo", NodeMatchers.isNotNull());
verifyThat("#progressBarSplashScreen", NodeMatchers.isNotNull());
verifyThat("#labelSplashScreenVersion", NodeMatchers.isNotNull());
verifyThat("#labelSplashScreenDate", NodeMatchers.isNotNull());
this.loggerGuiTesting.log(Level.INFO, "testIfOpeningScreenIsThere, succeeded!");
}
#Test
public void btestIfRadioButtonOneExist() {
assertThat("#sourcesOneRadioButton", is("#sourcesOneRadioButton"));
this.loggerGuiTesting.log(Level.INFO, "testIfRadioButtonOneExist, succeeded!");
}
#Test
public cnextTest() {
new StartAnotherGuiTest().run();
this.loggerGuiTesting.log(Level.INFO, "anotherTest, succeeded!");
}
}
The question is: how can I relaunch the application after each test?
It is difficult to answer without taking a look at the StartMain class. It looks like you are using a singleton pattern there. If thats the case I would create a new method in StartMain that sets the singleton instance to null so when getInstance is called again, it has to be re-created:
#After //This should be executed after each test
public void destroyApp()
{
StartMain.getInstance().destroy();
}
My #Before and #After methods are not picking up by Junit
public class TestSetup {
#Before
public void browserSetUp() {
// code for before a test
}
#After
public void tearDown() {
// code after a test
}
}
In Another class file I have defined
public class Steps{
#Step
public void step1() {
//Code for step 1
}
#Step
public void step2() {
// Code for Step 2
}
}
Finally I am calling those steps for my Test
public class Tests {
Steps step = new Steps();
#Test
public void TC_0001 {
step.step1();
step.step2();
}
}
#Test method are getting executed but the #Before and #After methods are not executing before #Test method.Do I have to include the TestSetup class to somewhere ? Any help will be appreciated.
**Thought 1: As I am using Maven to build, my #Before #After methods resides in a class (TestSetup.java - Name is not ending with *Test.java and may be thats why Maven is not picking it up for execution?
#Before and #After are used in the same class that your test is running. You should put this methods on your test class:
public class Tests {
Steps step = new Steps();
#Test
public void TC_0001 {
step.step1();
step.step2();
}
#Before
public void browserSetUp() {
// code for before a test
}
#After
public void tearDown() {
// code after a test
}
}
#Before and #After are only executed before a single test, if they are defined in the same class as the #Test. In your case, the TestSetup class contains no tests. So either you let Test inherit from TestSetup or you create a rule that is executed "around" your test.
Does anyone knows how to add a test Resource (i.e. one that is only for testing purposes and not added in run() method of the app)?
Here is an example:
public class MyTest {
#ClassRule
public static final DropwizardAppRule<TestConfiguration> RULE =
new DropwizardAppRule<TestConfiguration>(MyApp.class, "my-app-config.yaml");
#BeforeClass
public static void setUpBeforeClass() throws Exception
{
MyTest.RULE.getEnvironment().jersey().register(new JustForTestingResource());
}
#Test
public final void testTestResource()
{
Client client = new Client();
ClientResponse response = client.resource(
String.format("http://localhost:%d/rest/v1/test", RULE.getLocalPort()))
.get(ClientResponse.class);
assertThat(response.getStatus(), is(200));
}
}
and
public class JustForTestingRessource {
#GET
#Path("test")
#Produces(MediaType.APPLICATION_JSON)
public Response getInTestResource()
{
return Response.status(Status.OK).type(MediaType.TEXT_PLAIN).entity("get #Path(\"test\") is ok").build();
}
}
My problem is that the added resource is not added and I get resource not found 404 error response. It seems that I am registering the new resource after resource publishing and there is no refresh inside Dropwizard after start.
I dont want to extend my Application class and I dont want to insert test code into my real application code. Does anyone knows how to register the test resource without registering it in run() method of the Application?
This works, but a new class is needed:
public class TestService extends MyService{
#Override
public void run(
TestConfigurationconfiguration,
Environment environment) throws ClassNotFoundException
{
environment.jersey().register(new JustForTestingRessource());
super.run(configuration,environment);
}
}
Call in JUnit as already known:
#ClassRule
public static DropwizardAppRule<TestConfiguration> RULE =
new DropwizardAppRule<TestConfiguration>(TestService.class, "my-app-config.yaml");
Edit: Removing previous answer because it didn't solve your problem the way you wanted to do it.
I dug into the environment startup code and realized the reason why registering a controller didn't make it available is because jetty had already been started. If you stop jetty, register your controller and start jetty back up again, your resource will be available and you can use it in your test.
#BeforeClass
public static void setUpBeforeClass() throws Exception
{
MyTest.RULE.environment.applicationContext.stop()
MyTest.RULE.environment.jersey().register(new JustForTestingResource())
MyTest.RULE.environment.applicationContext.start()
}
You can test the Resource itself in a Jersey Container without starting a full dw-instance.
Check the "Testing Resources" section.
import static org.fest.assertions.api.Assertions.assertThat;
import static org.mockito.Mockito.*;
public class PersonResourceTest {
private static final PeopleStore dao = mock(PeopleStore.class);
#ClassRule
public static final ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new PersonResource(dao))
.build();
private final Person person = new Person("blah", "blah#example.com");
#Before
public void setup() {
when(dao.fetchPerson(eq("blah"))).thenReturn(person);
// we have to reset the mock after each test because of the
// #ClassRule, or use a #Rule as mentioned below.
reset(dao);
}
#Test
public void testGetPerson() {
assertThat(resources.client().resource("/person/blah").get(Person.class))
.isEqualTo(person);
verify(dao).fetchPerson("blah");
}
}
I had the similar issue with the #ClassRule, maybe it can help to somebody..
In my test (Groovy) the invocation of RULE.getApplication() or getEnvironment() from #BeforeClass method returned null:
def setupSpec() {
RULE.application.run()
}
shown
java.lang.NullPointerException: Cannot invoke method run() on null object
I.e. RULE.testSupport had both null application and environment.
I found out that the call to
RULE.testSupport.before()
just before run() solves the error:
def setupSpec() {
RULE.testSupport.before()
RULE.application.run()
}
And then #AfterClass method:
def cleanupSpec() {
RULE.testSupport.after()
}
Or just use #Rule instead of #ClassRule and call
def setup() {
RULE.application.run()
}
inside of #Before method instead of #BeforeClass.
Though It seems strange, maybe there is some other better solution exists..
public class TestMain extends Main{
public static void main(String ... args) throws Exception {
new TestMain().run(args);
}
#Override
public void initialize(Bootstrap<AppConfiguration> bootstrap) {
super.initialize(bootstrap);
bootstrap.addBundle(
new MigrationsBundle<AppConfiguration>() {
#Override
public DataSourceFactory getDataSourceFactory(
AppConfiguration configuration) {
return configuration.getDataSourceFactory();
}
});
}
}
My code has a bunch of unit tests dealing with some DB that I would like to have reset before each test. I am using the #FlywayTest annotation to perform this reset.
#Test
#FlywayTest
public void unitTest1 {
}
#Test
#FlywayTest
public void unitTest2 {
}
#Test
#FlywayTest
public void unitTest3 {
}
This works fine, but is there a way to do this without having to annotate each test with FlywayTest? I tried this but it doesn't work:
#Before
#FlywayTest
public void setup() {
}
#Test
public void unitTest1 {
}
#Test
public void unitTest2 {
}
#Test
public void unitTest3 {
}
Sorry for late anwser.
At the moment it is not possible but I will think about it if it is possible.
Please add a issue to https://github.com/flyway/flyway-test-extensions/issues
One early design issue was that use made a whole database reset only per test class and use the annotation #FlywayTest on method level only as test exception.
florian
I have an Integration Test Suite. I have a IntegrationTestBase class for all my tests to extend. This base class has a #Before (public void setUp()) and #After (public void tearDown()) method to establish API and DB connections. What I've been doing is just overriding those two methods in each testcase and calling super.setUp() and super.tearDown(). However this can cause problems if someone forgets to call the super or puts them at the wrong place and an exception is thrown and they forget to call super in the finally or something.
What I want to do is make the setUp and tearDown methods on the base class final and then just add our own annotated #Before and #After methods. Doing some initial tests it appears to always call in this order:
Base #Before
Test #Before
Test
Test #After
Base #After
but I'm just a little concerned that the order isn't guaranteed and that it could cause problems. I looked around and haven't seen anything on the subject. Does anyone know if I can do that and not have any problems?
Code:
public class IntegrationTestBase {
#Before
public final void setUp() { *always called 1st?* }
#After
public final void tearDown() { *always called last?* }
}
public class MyTest extends IntegrationTestBase {
#Before
public final void before() { *always called 2nd?* }
#Test
public void test() { *always called 3rd?* }
#After
public final void after() { *always called 4th?* }
}
Yes, this behaviour is guaranteed:
#Before:
The #Before methods of superclasses will be run before those of the current class, unless they are overridden in the current class. No other ordering is defined.
#After:
The #After methods declared in superclasses will be run after those of the current class, unless they are overridden in the current class.
One potential gotcha that has bitten me before:
I like to have at most one #Before method in each test class, because order of running the #Before methods defined within a class is not guaranteed. Typically, I will call such a method setUpTest().
But, although #Before is documented as The #Before methods of superclasses will be run before those of the current class. No other ordering is defined., this only applies if each method marked with #Before has a unique name in the class hierarchy.
For example, I had the following:
public class AbstractFooTest {
#Before
public void setUpTest() {
...
}
}
public void FooTest extends AbstractFooTest {
#Before
public void setUpTest() {
...
}
}
I expected AbstractFooTest.setUpTest() to run before FooTest.setUpTest(), but only FooTest.setupTest() was executed. AbstractFooTest.setUpTest() was not called at all.
The code must be modified as follows to work:
public void FooTest extends AbstractFooTest {
#Before
public void setUpTest() {
super.setUpTest();
...
}
}
I think based on the documentation of the #Before and #After the right conclusion is to give the methods unique names. I use the following pattern in my tests:
public abstract class AbstractBaseTest {
#Before
public final void baseSetUp() { // or any other meaningful name
System.out.println("AbstractBaseTest.setUp");
}
#After
public final void baseTearDown() { // or any other meaningful name
System.out.println("AbstractBaseTest.tearDown");
}
}
and
public class Test extends AbstractBaseTest {
#Before
public void setUp() {
System.out.println("Test.setUp");
}
#After
public void tearDown() {
System.out.println("Test.tearDown");
}
#Test
public void test1() throws Exception {
System.out.println("test1");
}
#Test
public void test2() throws Exception {
System.out.println("test2");
}
}
give as a result
AbstractBaseTest.setUp
Test.setUp
test1
Test.tearDown
AbstractBaseTest.tearDown
AbstractBaseTest.setUp
Test.setUp
test2
Test.tearDown
AbstractBaseTest.tearDown
Advantage of this approach: Users of the AbstractBaseTest class cannot override the setUp/tearDown methods by accident. If they want to, they need to know the exact name and can do it.
(Minor) disadvantage of this approach: Users cannot see that there are things happening before or after their setUp/tearDown. They need to know that these things are provided by the abstract class. But I assume that's the reason why they use the abstract class
If you turn things around, you can declare your base class abstract, and have descendants declare setUp and tearDown methods (without annotations) that are called in the base class' annotated setUp and tearDown methods.
You can use #BeforeClass annotation to assure that setup() is always called first. Similarly, you can use #AfterClass annotation to assure that tearDown() is always called last.
This is usually not recommended, but it is supported.
It's not exactly what you want - but it'll essentially keep your DB connection open the entire time your tests are running, and then close it once and for all at the end.
This isn't an answer to the tagline question, but it is an answer to the problems mentioned in the body of the question. Instead of using #Before or #After, look into using #org.junit.Rule because it gives you more flexibility. ExternalResource (as of 4.7) is the rule you will be most interested in if you are managing connections. Also, If you want guaranteed execution order of your rules use a RuleChain (as of 4.10). I believe all of these were available when this question was asked. Code example below is copied from ExternalResource's javadocs.
public static class UsesExternalResource {
Server myServer= new Server();
#Rule
public ExternalResource resource= new ExternalResource() {
#Override
protected void before() throws Throwable {
myServer.connect();
};
#Override
protected void after() {
myServer.disconnect();
};
};
#Test
public void testFoo() {
new Client().run(myServer);
}
}