Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gracefully shutdown test context #1135

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2010 the original author or authors.
* Copyright 2006-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -74,9 +74,7 @@
* for replacing dynamic content(variables and functions) in message payloads and headers.
*/
public class TestContext implements ReferenceResolverAware, TestActionListenerAware {
/**
* Logger
*/

private static final Logger logger = LoggerFactory.getLogger(TestContext.class);

/**
Expand Down Expand Up @@ -439,9 +437,13 @@ public CitrusRuntimeException handleError(String testName, String packageName, S
CitrusRuntimeException exception = new CitrusRuntimeException(message, cause);

// inform test listeners with failed test
testListeners.onTestStart(dummyTest);
testListeners.onTestFailure(dummyTest, exception);
testListeners.onTestFinish(dummyTest);
try {
testListeners.onTestStart(dummyTest);
testListeners.onTestFailure(dummyTest, exception);
testListeners.onTestFinish(dummyTest);
} catch (Exception e) {
logger.warn("Executing error handler listener failed!", e);
}

return exception;
}
Expand Down Expand Up @@ -903,7 +905,8 @@ public boolean isSuccess(TestResult testResult) {
/**
* Empty test case implementation used as test result when tests fail before execution.
*/
private static class EmptyTestCase implements TestCase {
static class EmptyTestCase implements TestCase {

private final String testName;
private final String packageName;

Expand Down
@@ -0,0 +1,87 @@
package org.citrusframework.context;

import org.citrusframework.exceptions.CitrusRuntimeException;
import org.citrusframework.report.TestListener;
import org.citrusframework.report.TestListeners;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

public class TestContextUnitTest {

private TestContext fixture;

@BeforeTest
void beforeTestClass() {
fixture = new TestContext();
}

@Test
public void handleErrorGracefullyHandlesErrorInTestStartListener() {
var testListenerMock = attachTestListenerMockToFixture();

var cause = new CitrusRuntimeException("thrown with a purpose!");
doThrow(cause).when(testListenerMock).onTestStart(any(TestContext.EmptyTestCase.class));

invokeHandleErrorOnFixture(cause);

verify(testListenerMock).onTestStart(any(TestContext.EmptyTestCase.class));
verifyNoMoreInteractions(testListenerMock);
}

@Test
public void handleErrorGracefullyHandlesErrorInTestFailureListener() {
var testListenerMock = attachTestListenerMockToFixture();

var cause = new CitrusRuntimeException("thrown with a purpose!");
doThrow(cause).when(testListenerMock).onTestFailure(any(TestContext.EmptyTestCase.class), any(CitrusRuntimeException.class));

invokeHandleErrorOnFixture(cause);

verify(testListenerMock).onTestStart(any(TestContext.EmptyTestCase.class));
verify(testListenerMock).onTestFailure(any(TestContext.EmptyTestCase.class), any(CitrusRuntimeException.class));
verifyNoMoreInteractions(testListenerMock);
}

@Test
public void handleErrorGracefullyHandlesErrorInTestFinishListener() {
var testListenerMock = attachTestListenerMockToFixture();

var cause = new CitrusRuntimeException("thrown with a purpose!");
doThrow(cause).when(testListenerMock).onTestFinish(any(TestContext.EmptyTestCase.class));

invokeHandleErrorOnFixture(cause);

verify(testListenerMock).onTestStart(any(TestContext.EmptyTestCase.class));
verify(testListenerMock).onTestFailure(any(TestContext.EmptyTestCase.class), any(CitrusRuntimeException.class));
verify(testListenerMock).onTestFinish(any(TestContext.EmptyTestCase.class));
}

private TestListener attachTestListenerMockToFixture() {
var testListeners = new TestListeners();

var testListenerMock = mock(TestListener.class);
testListeners.addTestListener(testListenerMock);

fixture.setTestListeners(testListeners);

return testListenerMock;
}

private void invokeHandleErrorOnFixture(CitrusRuntimeException cause) {
var testName = "test name";
var packageName = "package name";

var message = "additional message";

var citrusRuntimeException = fixture.handleError(testName, packageName, message, cause);
assertEquals(citrusRuntimeException.getMessage(), message);
assertEquals(citrusRuntimeException.getCause(), cause);
}
}