Can #Before and/or #After methods inspect the expected parameter? - java

Part of a test fixture checks that no errors were logged during a test:
#After
public void testname() {
if(accumulatedErrors()) {
fail("Errors were recorded during test");
}
}
But for a test that is expected to fail, like this:
#Test(expected = IllegalStateException.class)
public void shouldExplode() throws Exception {
doExplodingStuff();
}
the #After method should invert the check:
#After
public void testname() {
if (failureIsExpected()) {
assertTrue("No errors were recorded during test", accumulatedErrors());
} else {
assertFalse("Errors were recorded during test", accumulatedErrors());
}
}
Is there a way to inspect the expected parameter of the executed test from the #After method?
Of course, the test could specify expectToFail=true or something like that, but I would like to avoid that duplication.

Why you cannot add assertTrue or assertFalse in each test method ?
You solution seems to me too complicated.
Method annotated with #After should be used to release resources.

Using catch-exception, you can move the check for an exception inside the method instead of outside the method:
#Test
public void shouldExplode() throws Exception {
catchException(this).doExplodingStuff();
assertTrue(caughtException() instanceof IllegalStateException);
}

Related

Mockito How to mock and assert a thrown exception

I have this junit:
#RunWith(MockitoJUnitRunner.class)
public class SecurityManagerServiceTest {
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
//given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
when(securityManagerService.restoreRight("a")).thenThrow(SecurityException.class);
}
but I have this error:
unnecessary Mockito stubbings
I also tried:
#Mock
private SecurityManagerService securityManagerService = mock(SecurityManagerService.class);
#Test
public void testRequireAll() {
when(securityManagerService.loggerUser()).thenReturn(fakeUser());
doCallRealMethod().when(securityManagerService).requireRight(anyString());
given(securityManagerService.restoreRight("a")).willThrow(SecurityException.class);
}
The problem is that you are stubbing, but not really testing anything. And if you are not testing anything, then there is no need for stubbing. That's why you have unnecessary Mockito stubbings.
I assume that you want to test your SecurityManagerService. If you want to do that, you need to create an instance or have a bean of that type, but not a mock. Then you call the method that you want to test and assert that you get the expected result.
If you expect to get an exception you can test it like this:
JUnit4, just enhance you #Test annotation:
#Test(expected=SecurityException.class)
JUnit 5:
#Test
void testExpectedException() {
Assertions.assertThrows(SecurityException.class, () -> {
//Code under test
});
}

How to write junit test for exceptions which are explicitly thrown

I have a method that takes in the String, and check if it contains another string. If it does, then it throws a custom exception.
Class Test{
String s2="test";
public void testex(String s1){
if(s1.contains(s2))
throw new customException();
}
}
I am trying to write a unit test for this:
#Test (expected = customException.class){
when(s1.contains(s2)
.thenThrow(new customException());
}
However, my test is failing with the error as-- java.lang.Exception: Unexpected exception, expected customException but was<org.mockito.exceptions.misusing.MissingMethodInvocationException>
This test doesn't seem to be particularly useful, but I believe your issue is that Mockito's when() expects a method call for a mocked object.
#Test(expcted = CustomException.class)
public void testExMethod() {
#Mock
private Test test;
when(test.testEx()).thenThrow(CustomException.class);
test.testEx("test string");
}
I'm not quite following your example test. It looks like you're mocking your actual class with Mockito rather than writing a junit test. I would write a test like this:
With junit's assertThrows method:
#Test
void stringContainingThrowsError() {
Test myClassThatImTesting = new Test();
assertThrows(CustonException.class, () -> myClassThatImTesting.testex("test"))
}
With a normal assertion:
#Test
void stringContainingThrowsError() {
Test myClassThatImTesting = new Test();
try {
myClassThatImTesting.testex("test");
fail();
} catch (Exception ex) {
assertTrue(ex instanceof CustomException);
}
}

Setup JUnit test timeout using reflection

I have found so far 2 ways to setup JUnit test timeout. Either using:
#Test(timeout=XXX)
Or using something like:
#ClassRule
public static Timeout timeoutRule = new Timeout(XXX, TimeUnit.MILLISECONDS);
In my case, I have a Test Runner as a main class to run all my test suites, so I can execute the tests as an executable jar.
I'd like this runner to setup the timeouts dinamically using reflection.
Is it possible to do?
You could add the timeout feature to a custom test runner like so:
public class TimeoutTestRunner extends BlockJUnit4ClassRunner {
public TimeoutTestRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) {
return FailOnTimeout.builder()
// you'll probably want to configure/inject this value rather than hardcode it ...
.withTimeout(1, TimeUnit.MILLISECONDS)
.build(next);
}
}
Using this test runner the tests in the following test case ...
#RunWith(TimeoutTestRunner.class)
public class YourTest {
#Test
public void willTimeout() throws InterruptedException {
Thread.sleep(50);
assertTrue(true);
}
#Test
public void willNotTimeout() throws InterruptedException {
assertTrue(true);
}
}
... will behave as follows:
willTimeout: will fail with a TestTimedOutException
willNotTimeout: will pass
Although you will need your tests to be run via this runner you will be able to control their timeout setting from one place and provide custom timeout derivation strategies such as if test name matches <some regex> then timeout is x else ....

Selenium Exception Handling Design

In Order to prevent exception handling in each method in selenium page objects, i thought to have a general exception handling, a try catch in the test block,
other handlers only if more specific handling required,
Now the issue is that this process needs to be written in each test...
is there a way to make the test methods have this common test handling written once for all tests?
#Test
public void test(WebDriver driver) {
try {
// common code in the try block
// using testNG may be moved to #BeforeMethod And #AfterMethod
Logger.log("Test Started....");
Logger.log("Test Ended....");
Assert.assertAll();
}
catch() {
// in Case Automation Fails, common operations required
ScreenShoot.getScreenShoot();
}
finally
{
// finally for all tests
driver.close();
}
}
If you are using jUnit, you can create a TestWatcher Rule (the TestNG alternative ITestListener is mentioned here).
public class YourTestWatcherImplementation extends TestWatcher() {
#Override
protected void starting(Description description) {
// initialize your WebDriver
// perhaps login to your tested application?
}
#Override
protected void finished(Description description) {
// shutdown your WebDriver
}
#Override
protected void failed(Throwable error,
Description description) {
// take a screenshot
// do more error handling/reporting
}
}
This way, your tests only contain the actual test code and you got all the preparation/tearDown in one place.
Each test class only needs a public member variable with the #Rule annotation like this:
public class OneOfYourTestClasses {
#Rule
public TestWatcher watcher = new YourTestWatcherImplementation();
#Test
public void testSomething() {
...
}
#Test
public void testEvenMore() {
...
}
}
I'd suggest to create parent test class, which all other tests will extend. In this parent test class, create #AfterMethod, which will take screenshot on failure. Here is an example (although without inheritance):
http://artoftesting.com/automationTesting/screenShotInSelenium.html

testNG annotation which would equal to "finally" in java?

i don't know if my question was clear, but i am using testNG and i have this:
#Test
public void passengerServiceTest() {
...
}
#AfterTest
public void deleteCreatedPassenger() {
...
}
I want to execute my deleteCreatedPassenger() method after passengerServiceTest, also, i want that in case of deleteCreatedPassenger fails, passengerServiceTest fails too, in other words, i want that both of them be the same test, so if one them fails, test fails.
So i tried with the annotations #AfterTest, #AfterMethod, #AfterClass and all make two tests as "separated" tests.
Do you know how to do this? Regards
You don't need annotations to achieve this, since it's exactly what the finally block is intended for:
#Test
public void passengerServiceTest() {
try {
//test code
} finally {
deleteCreatedPassenger();
}
}
public void deleteCreatedPassenger() {
...
}
If the delete throws an exception then your service test fails.
Annotations are useful in certain scenarios, you shouldn't aim to use them over core language constructs.
alwaysRun
https://testng.org/doc/documentation-main.html
Ex:
#AfterTest(alwaysRun = true)
public void deleteOldValuesFromDatabase() {
...
}
Docs say that this will cause the method to run "even if one or more methods invoked previously failed or was skipped"

Categories

Resources