Will Junit execute the #Test case when the code in the #before Section fails? - junit4

I'm new to Junit.
If I execute something in the #before part, and my code fails. e.g. I want to make a server connection, but it fails for some reason.
Will Junit execute my Test in the #Test section even if the #before fails? Because then my test would fail because I haven't a server connection. How can I handle it if its the case?

You can try this out with a basic junit.
public class SamplePlayTest {
#Before
public void setup() {
System.out.println("Before called");
throw new RuntimeException();
}
#Test
public void test() {
System.out.println("Test case called");
}
}
This gives output as
Before called
And fails with error java.lang.RuntimeException. Test case called is not printed.

Related

Insert test record for Spring Batch integration test with #Transactional(propagation = NOT_SUPPORTED) does not roll back

I would like to insert a test record while testing my Spring Batch job.
Normally I'd annotate the test class with #Transactional, but that does not work with a test class that is annotated with #SpringBatchTest.
#SpringBatchTest
#SpringBootTest
#Transactional
public class JobTest {
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#Autowired
private JdbcTemplate jdbcTemplate;
#Test
void someTest() throws Exception {
jdbcTemplate.update("insert into some_table (some_col1, some_col2) values ('foo', 'bar')");
jobLauncherTestUtils.launchJob();
}
}
Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove #Transactional annotations from client).
java.lang.IllegalStateException: Existing transaction detected in JobRepository. Please fix this and try again (e.g. remove #Transactional annotations from client).
at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:177)
I have also tried #Transactional(propagation = NOT_SUPPORTED), but the record does not rollback. This was the suggestion in https://stackoverflow.com/a/46546171/10243546
I just want test records for the test, so I wasn't sure if this answer applies (https://stackoverflow.com/a/55001568/10243546) since this is just for a test.
You need to move test setup outside the test method, for example in a method annotated with #Before (JUnit 4) or #BeforeEach (JUnit 5). Something like:
#Before
public void initData() {
jdbcTemplate.update("insert into some_table (some_col1, some_col2) values ('foo', 'bar')");
}
#Test
void someTest() throws Exception {
jobLauncherTestUtils.launchJob();
}
I was able to get such a test running using TransactionTemplate in the test method:
#SpringBatchTest
class MyJobTest {
// [...]
#Autowired
PlatformTransactionManager txManager;
#Test
void some_test() {
// setup must be done in a custom transaction due too #SpringBatchTest
new TransactionTemplate(txManager).executeWithoutResult(t -> {
// use jdbcTemplate or entityManager to insert data
jdbcTemplate.update("insert into some_table (some_col1, some_col2) values ('foo', 'bar')");
});
jobLauncherTestUtils.launchJob();
}
}

Test for internal server errors in rest api

I want to write unit test cases for negative scenarios for my REST API spring boot application.
The controller methods looks like this:
#RequestMapping(path = "/getcalc/srn/{srn}", method = RequestMethod.GET)
public RestResponse<List<BookMarkMRPostProcessCalc>> fetchLatestPostProcessCalc(#PathVariable("srn") String srn) {
try {
List<BookMarkMRPostProcessCalc> calcList = bookMarkMrPostProcessCalcService.getPostProcessCalc(srn);
return ResponseUtil.prepareRestResponse(calcList);
} catch (BookMarkServiceException e) {
return ResponseUtil.prepareErrorRestResponse(e.getMessage(), "", e.toString());
}
}
The positive scenario works fine. I want to write test cases for the scenario when BookMarkServiceException occurs or mock it. How can we achieve this in junit?
One way of doing it is as below:
#RunWith(SpringRunner.class)
public class YourClassNameTest {
#InjectMocks
pricvate YourClassName yourClassName;
#Rule
public ExpectedException exceptionRule = ExpectedException.none();
#Test
public void fetchLatestPostProcessCalcTest(){
expectedException.expect(BookMarkServiceException.class);
yourClassName.fetchLatestPostProcessCalc("input that would generate error");
}

How to make NUnit stop executing tests on first failure

We use NUnit to execute integration tests. These tests are very time consuming. Often the only way to detect a failure is on a timeout.
I would like the tests to stop executing as soon as a single failure is detected.
Is there a way to do this?
Using nunit-console, you can achieve this by using the /stoponerror command line parameter.
See here for the command line reference.
For nunit-console v3, it changes to --stoponerror (see here for the command line reference).
I'm using NUnit 3 and the following code works for me.
public class SomeTests {
private bool stop;
[SetUp]
public void SetUp()
{
if (stop)
{
Assert.Inconclusive("Previous test failed");
}
}
[TearDown]
public void TearDown()
{
if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed)
{
stop = true;
}
}
}
Alternatively you could make this an abstract class and derive from it.
This is probably not the ideal solution, but it does what you require i.e. Ignore remaining tests if a test has failed.
[TestFixture]
public class MyTests
{
[Test]
public void Test1()
{
Ascertain(() => Assert.AreEqual(0, 1));
}
[Test]
public void Test2()
{
Ascertain(() => Assert.AreEqual(1, 1));
}
private static void Ascertain( Action condition )
{
try
{
condition.Invoke();
}
catch (AssertionException ex)
{
Thread.CurrentThread.Abort();
}
}
}
Since TestFixtureAttribute is inheritable, so you could potentially create a base class with this attribute decorated on it and have the Ascertain protected Method in it and derive all TestFixture classes from it.
The only downside being, you'll have to refactor all your existing Assertions.

junit annotation

I wish to launch the GUI application 2 times from Java test. How should we use #annotation in this case?
public class Toto {
#BeforeClass
public static void setupOnce() {
final Thread thread = new Thread() {
public void run() {
//launch appli
}
};
try {
thread.start();
} catch (Exception ex) { }
}
}
public class Test extends toto {
#Test
public void test() {
setuptonce();
closeAppli();
}
#test
public void test2()
{
setuptonce();
}
}
To launch it a second time, which annotation should I use? #afterclass?
Method annotated with #BeforeClass means that it is run once before any of the test methods are run in the test class. Method annotated with #Before is run once before every test method in the class. The counterparts for these are #AfterClass and #After.
Probably you are aiming for something like the following.
#BeforeClass
public static void setUpClass() {
// Initialize stuff once for ALL tests (run once)
}
#Before
public void setUp() {
// Initialize stuff before every test (this is run twice in this example)
}
#Test
public void test1() { /* Do assertions etc. */ }
#Test
public void test2() { /* Do assertions etc. */ }
#AfterClass
public static void tearDownClass() {
// Do something after ALL tests have been run (run once)
}
#After
public void tearDown() {
// Do something after each test (run twice in this example)
}
You don't need to explicitly call the #BeforeClass method in your test methods, JUnit does that for you.
The #BeforeClass annotation is used to run something once, before test actually runs.
So, depending on what do you want to get (and why), you can simply wrap launch code in a cycle, move launch code in other method and call it from somewhere else or write separate test case.

Starting Selenium with custom Firefox profile from Eclipse

I'm running Selenium tests from within Eclipse, but I can't load a custom Firefox profile.
Most sources suggest I need to launch the Selenium Server like this:
java -jar selenium-server.jar -firefoxProfileTemplate </path/to/template/>
But when launching my test from within Eclipse it doesn't use that - the tests will run if the Selenium Server isn't running.
This thread suggests that I can set the profile in the DefaultSelenium constructor:
Selenium RC - disabling browser cookie
But the code generated for me by Selenium IDE (Firefox plugin) doesn't use that constructor:
package com.example.tests;
import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;
public class Example extends SeleneseTestCase {
public void setUp() throws Exception {
setUp("http://www.example.com/", "*firefox");
}
public void testExample() throws Exception {
selenium.open("/");
selenium.click("//body");
}
}
Where should I set the DefaultSelenium configuration options? Or is there some other method I can use to load my custom Firefox template?
Thanks!
Stu
I made a SeleniumTestCase that starts/stops the server before/after each test class and starts/stops the Selenium instance before/after each test:
public class SeleniumTestCase {
protected static Selenium selenium;
protected static AppNavUtils appNavUtils;
#BeforeClass
public static void setUpBeforeClass() throws Exception {
SeleniumServerControl.getInstance().startSeleniumServer();
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
SeleniumServerControl.getInstance().stopSeleniumServer();
}
#Before
public void setUp() throws Exception {
// Replace "*chrome" with "*firefox" for Selenium > 1.0
selenium = new DefaultSelenium("localhost", 5444, "*chrome", "http://localhost:8080/");
selenium.start();
appNavUtils = new AppNavUtils(selenium);
}
#After
public void tearDown() throws Exception {
selenium.stop();
}
}
The SeleniumServerControl starts and stops the server:
public class SeleniumServerControl {
private static final SeleniumServerControl instance = new SeleniumServerControl();
public static SeleniumServerControl getInstance()
{
return instance;
}
private SeleniumServer server = null;
protected SeleniumServerControl(){}
public void startSeleniumServer() {
if (server == null) {
RemoteControlConfiguration rcc = new RemoteControlConfiguration();
rcc.setPort(5444);
//rcc.setFirefoxProfileTemplate(newFirefoxProfileTemplate)
server = new SeleniumServer(rcc);
}
server.start();
}
public void stopSeleniumServer()
{
if (server != null) {
server.stop();
server = null;
}
}
}
the version of code you have above assumes that you are running your tests against localhost on port 4444 thats why it is has 2 parameters in the setup.
To set up eclipse to run it you will need to update the run configuration. That is under
Run > Run Configurations
Have a look for the item that has selenium in it and add the config above so that when it runs it will pick it up and run.
I personally just fire up the server when I start working by running a batch file and kill it at the end of the day.