Migrate TestNG assertions to AssertJ
Migrate all existing TestNG based assertions to AssertJ and add Checkstyle rules to ensure they don't return. See gh-23022
This commit is contained in:
parent
50cc23ca55
commit
4f4427f550
|
@ -182,8 +182,7 @@ public class ClassLevelDirtiesContextTestNGTests {
|
|||
|
||||
|
||||
protected void assertApplicationContextWasAutowired() {
|
||||
org.testng.Assert.assertNotNull(this.applicationContext,
|
||||
"The application context should have been autowired.");
|
||||
assertThat(this.applicationContext).as("The application context should have been autowired.").isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,8 +25,7 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.tests.sample.beans.Employee;
|
||||
import org.springframework.tests.sample.beans.Pet;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for
|
||||
|
@ -50,11 +49,11 @@ public class AnnotationConfigTestNGSpringContextTests extends AbstractTestNGSpri
|
|||
|
||||
@Test
|
||||
void autowiringFromConfigClass() {
|
||||
assertNotNull(employee, "The employee should have been autowired.");
|
||||
assertEquals(employee.getName(), "John Smith");
|
||||
assertThat(employee).as("The employee should have been autowired.").isNotNull();
|
||||
assertThat(employee.getName()).isEqualTo("John Smith");
|
||||
|
||||
assertNotNull(pet, "The pet should have been autowired.");
|
||||
assertEquals(pet.getName(), "Fido");
|
||||
assertThat(pet).as("The pet should have been autowired.").isNotNull();
|
||||
assertThat(pet.getName()).isEqualTo("Fido");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,10 +38,9 @@ import org.springframework.transaction.PlatformTransactionManager;
|
|||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.transaction.TransactionAssert.assertThatTransaction;
|
||||
import static org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Integration tests that verify support for
|
||||
|
@ -86,12 +85,13 @@ public class AnnotationConfigTransactionalTestNGSpringContextTests
|
|||
}
|
||||
|
||||
private void assertNumRowsInPersonTable(int expectedNumRows, String testState) {
|
||||
assertEquals(countRowsInTable("person"), expectedNumRows, "the number of rows in the person table ("
|
||||
+ testState + ").");
|
||||
assertThat(countRowsInTable("person"))
|
||||
.as("the number of rows in the person table (" + testState + ").")
|
||||
.isEqualTo(expectedNumRows);
|
||||
}
|
||||
|
||||
private void assertAddPerson(final String name) {
|
||||
assertEquals(createPerson(name), 1, "Adding '" + name + "'");
|
||||
private void assertAddPerson(String name) {
|
||||
assertThat(createPerson(name)).as("Adding '%s'", name).isEqualTo(1);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
@ -104,20 +104,20 @@ public class AnnotationConfigTransactionalTestNGSpringContextTests
|
|||
|
||||
@AfterClass
|
||||
void afterClass() {
|
||||
assertEquals(numSetUpCalls, NUM_TESTS, "number of calls to setUp().");
|
||||
assertEquals(numSetUpCallsInTransaction, NUM_TX_TESTS, "number of calls to setUp() within a transaction.");
|
||||
assertEquals(numTearDownCalls, NUM_TESTS, "number of calls to tearDown().");
|
||||
assertEquals(numTearDownCallsInTransaction, NUM_TX_TESTS, "number of calls to tearDown() within a transaction.");
|
||||
assertThat(numSetUpCalls).as("number of calls to setUp().").isEqualTo(NUM_TESTS);
|
||||
assertThat(numSetUpCallsInTransaction).as("number of calls to setUp() within a transaction.").isEqualTo(NUM_TX_TESTS);
|
||||
assertThat(numTearDownCalls).as("number of calls to tearDown().").isEqualTo(NUM_TESTS);
|
||||
assertThat(numTearDownCallsInTransaction).as("number of calls to tearDown() within a transaction.").isEqualTo(NUM_TX_TESTS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void autowiringFromConfigClass() {
|
||||
assertNotNull(employee, "The employee should have been autowired.");
|
||||
assertEquals(employee.getName(), "John Smith");
|
||||
assertThat(employee).as("The employee should have been autowired.").isNotNull();
|
||||
assertThat(employee.getName()).isEqualTo("John Smith");
|
||||
|
||||
assertNotNull(pet, "The pet should have been autowired.");
|
||||
assertEquals(pet.getName(), "Fido");
|
||||
assertThat(pet).as("The pet should have been autowired.").isNotNull();
|
||||
assertThat(pet.getName()).isEqualTo("Fido");
|
||||
}
|
||||
|
||||
@BeforeTransaction
|
||||
|
@ -154,7 +154,7 @@ public class AnnotationConfigTransactionalTestNGSpringContextTests
|
|||
|
||||
@AfterTransaction
|
||||
void afterTransaction() {
|
||||
assertEquals(deletePerson(YODA), 1, "Deleting yoda");
|
||||
assertThat(deletePerson(YODA)).as("Deleting yoda").isEqualTo(1);
|
||||
assertNumRowsInPersonTable(1, "after a transactional test method");
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,9 @@ import org.springframework.tests.sample.beans.Pet;
|
|||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.transaction.TransactionAssert.assertThatTransaction;
|
||||
import static org.springframework.transaction.support.TransactionSynchronizationManager.isActualTransactionActive;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Combined integration test for {@link AbstractTestNGSpringContextTests} and
|
||||
|
@ -115,10 +112,10 @@ public class ConcreteTransactionalTestNGSpringContextTests extends AbstractTrans
|
|||
|
||||
@AfterClass
|
||||
void afterClass() {
|
||||
assertEquals(numSetUpCalls, NUM_TESTS, "number of calls to setUp().");
|
||||
assertEquals(numSetUpCallsInTransaction, NUM_TX_TESTS, "number of calls to setUp() within a transaction.");
|
||||
assertEquals(numTearDownCalls, NUM_TESTS, "number of calls to tearDown().");
|
||||
assertEquals(numTearDownCallsInTransaction, NUM_TX_TESTS, "number of calls to tearDown() within a transaction.");
|
||||
assertThat(numSetUpCalls).as("number of calls to setUp().").isEqualTo(NUM_TESTS);
|
||||
assertThat(numSetUpCallsInTransaction).as("number of calls to setUp() within a transaction.").isEqualTo(NUM_TX_TESTS);
|
||||
assertThat(numTearDownCalls).as("number of calls to tearDown().").isEqualTo(NUM_TESTS);
|
||||
assertThat(numTearDownCallsInTransaction).as("number of calls to tearDown() within a transaction.").isEqualTo(NUM_TX_TESTS);
|
||||
}
|
||||
|
||||
@BeforeMethod
|
||||
|
@ -147,7 +144,7 @@ public class ConcreteTransactionalTestNGSpringContextTests extends AbstractTrans
|
|||
|
||||
@AfterTransaction
|
||||
void afterTransaction() {
|
||||
assertEquals(deletePerson(YODA), 1, "Deleting yoda");
|
||||
assertThat(deletePerson(YODA)).as("Deleting yoda").isEqualTo(1);
|
||||
assertNumRowsInPersonTable(1, "after a transactional test method");
|
||||
}
|
||||
|
||||
|
@ -156,57 +153,60 @@ public class ConcreteTransactionalTestNGSpringContextTests extends AbstractTrans
|
|||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyBeanNameSet() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertTrue(this.beanName.startsWith(getClass().getName()), "The bean name of this test instance " +
|
||||
"should have been set to the fully qualified class name due to BeanNameAware semantics.");
|
||||
assertThat(this.beanName)
|
||||
.as("The bean name of this test instance should have been set to the fully qualified class name due to BeanNameAware semantics.")
|
||||
.startsWith(getClass().getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyApplicationContextSet() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertNotNull(super.applicationContext,
|
||||
"The application context should have been set due to ApplicationContextAware semantics.");
|
||||
assertThat(super.applicationContext)
|
||||
.as("The application context should have been set due to ApplicationContextAware semantics.")
|
||||
.isNotNull();
|
||||
Employee employeeBean = (Employee) super.applicationContext.getBean("employee");
|
||||
assertEquals(employeeBean.getName(), "John Smith", "employee's name.");
|
||||
assertThat(employeeBean.getName()).as("employee's name.").isEqualTo("John Smith");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyBeanInitialized() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertTrue(beanInitialized,
|
||||
"This test instance should have been initialized due to InitializingBean semantics.");
|
||||
assertThat(beanInitialized)
|
||||
.as("This test instance should have been initialized due to InitializingBean semantics.")
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyAnnotationAutowiredFields() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertNull(nonrequiredLong, "The nonrequiredLong field should NOT have been autowired.");
|
||||
assertNotNull(pet, "The pet field should have been autowired.");
|
||||
assertEquals(pet.getName(), "Fido", "pet's name.");
|
||||
assertThat(nonrequiredLong).as("The nonrequiredLong field should NOT have been autowired.").isNull();
|
||||
assertThat(pet).as("The pet field should have been autowired.").isNotNull();
|
||||
assertThat(pet.getName()).as("pet's name.").isEqualTo("Fido");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyAnnotationAutowiredMethods() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertNotNull(employee, "The setEmployee() method should have been autowired.");
|
||||
assertEquals(employee.getName(), "John Smith", "employee's name.");
|
||||
assertThat(employee).as("The setEmployee() method should have been autowired.").isNotNull();
|
||||
assertThat(employee.getName()).as("employee's name.").isEqualTo("John Smith");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyResourceAnnotationInjectedFields() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertEquals(foo, "Foo", "The foo field should have been injected via @Resource.");
|
||||
assertThat(foo).as("The foo field should have been injected via @Resource.").isEqualTo("Foo");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Transactional(propagation = Propagation.NOT_SUPPORTED)
|
||||
void verifyResourceAnnotationInjectedMethods() {
|
||||
assertThatTransaction().isNotActive();
|
||||
assertEquals(bar, "Bar", "The setBar() method should have been injected via @Resource.");
|
||||
assertThat(bar).as("The setBar() method should have been injected via @Resource.").isEqualTo("Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -227,12 +227,13 @@ public class ConcreteTransactionalTestNGSpringContextTests extends AbstractTrans
|
|||
}
|
||||
|
||||
private void assertNumRowsInPersonTable(int expectedNumRows, String testState) {
|
||||
assertEquals(countRowsInTable("person"), expectedNumRows,
|
||||
"the number of rows in the person table (" + testState + ").");
|
||||
assertThat(countRowsInTable("person"))
|
||||
.as("the number of rows in the person table (" + testState + ").")
|
||||
.isEqualTo(expectedNumRows);
|
||||
}
|
||||
|
||||
private void assertAddPerson(String name) {
|
||||
assertEquals(createPerson(name), 1, "Adding '" + name + "'");
|
||||
assertThat(createPerson(name)).as("Adding '" + name + "'").isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,10 +23,8 @@ import org.springframework.test.annotation.DirtiesContext;
|
|||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.TestContextManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.transaction.TransactionAssert.assertThatTransaction;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNotSame;
|
||||
import static org.testng.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -56,10 +54,12 @@ public class DirtiesContextTransactionalTestNGSpringContextTests extends Abstrac
|
|||
|
||||
private void performCommonAssertions() {
|
||||
assertThatTransaction().isActive();
|
||||
assertNotNull(super.applicationContext,
|
||||
"The application context should have been set due to ApplicationContextAware semantics.");
|
||||
assertNotNull(super.jdbcTemplate,
|
||||
"The JdbcTemplate should have been created in setDataSource() via DI for the DataSource.");
|
||||
assertThat(super.applicationContext)
|
||||
.as("The application context should have been set due to ApplicationContextAware semantics.")
|
||||
.isNotNull();
|
||||
assertThat(super.jdbcTemplate)
|
||||
.as("The JdbcTemplate should have been created in setDataSource() via DI for the DataSource.")
|
||||
.isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -72,15 +72,17 @@ public class DirtiesContextTransactionalTestNGSpringContextTests extends Abstrac
|
|||
@Test(dependsOnMethods = { "dirtyContext" })
|
||||
public void verifyContextWasDirtied() {
|
||||
performCommonAssertions();
|
||||
assertNotSame(super.applicationContext, this.dirtiedApplicationContext,
|
||||
"The application context should have been 'dirtied'.");
|
||||
assertThat(super.applicationContext)
|
||||
.as("The application context should have been 'dirtied'.")
|
||||
.isNotSameAs(this.dirtiedApplicationContext);
|
||||
this.dirtiedApplicationContext = super.applicationContext;
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = { "verifyContextWasDirtied" })
|
||||
public void verifyContextWasNotDirtied() {
|
||||
assertSame(this.applicationContext, this.dirtiedApplicationContext,
|
||||
"The application context should NOT have been 'dirtied'.");
|
||||
assertThat(this.applicationContext)
|
||||
.as("The application context should NOT have been 'dirtied'.")
|
||||
.isSameAs(this.dirtiedApplicationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.springframework.test.annotation.DirtiesContext.ClassMode;
|
|||
import org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests;
|
||||
import org.springframework.test.context.transaction.ejb.dao.TestEntityDao;
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for all TestNG-based tests involving EJB transaction
|
||||
|
@ -53,13 +53,13 @@ public abstract class AbstractEjbTxDaoTestNGTests extends AbstractTransactionalT
|
|||
@Test
|
||||
public void test1InitialState() {
|
||||
int count = dao.getCount(TEST_NAME);
|
||||
assertEquals("New TestEntity should have count=0.", 0, count);
|
||||
assertThat(count).as("New TestEntity should have count=0.").isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "test1InitialState")
|
||||
public void test2IncrementCount1() {
|
||||
int count = dao.incrementCount(TEST_NAME);
|
||||
assertEquals("Expected count=1 after first increment.", 1, count);
|
||||
assertThat(count).as("Expected count=1 after first increment.").isEqualTo(1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,10 +70,10 @@ public abstract class AbstractEjbTxDaoTestNGTests extends AbstractTransactionalT
|
|||
@Test(dependsOnMethods = "test2IncrementCount1")
|
||||
public void test3IncrementCount2() {
|
||||
int count = dao.getCount(TEST_NAME);
|
||||
assertEquals("Expected count=1 after test2IncrementCount1().", 1, count);
|
||||
assertThat(count).as("Expected count=1 after test2IncrementCount1().").isEqualTo(1);
|
||||
|
||||
count = dao.incrementCount(TEST_NAME);
|
||||
assertEquals("Expected count=2 now.", 2, count);
|
||||
assertThat(count).as("Expected count=2 now.").isEqualTo(2);
|
||||
}
|
||||
|
||||
@AfterMethod(alwaysRun = true)
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.testng.annotations.Test;
|
|||
import org.springframework.test.annotation.Rollback;
|
||||
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Extension of {@link CommitForRequiredEjbTxDaoTestNGTests} which sets the default
|
||||
|
@ -52,10 +52,10 @@ public class RollbackForRequiredEjbTxDaoTestNGTests extends CommitForRequiredEjb
|
|||
// participate in the existing transaction (if present), which in this case is the
|
||||
// transaction managed by the TestContext framework which will be rolled back
|
||||
// after each test method.
|
||||
assertEquals("Expected count=0 after test2IncrementCount1().", 0, count);
|
||||
assertThat(count).as("Expected count=0 after test2IncrementCount1().").isEqualTo(0);
|
||||
|
||||
count = dao.incrementCount(TEST_NAME);
|
||||
assertEquals("Expected count=1 now.", 1, count);
|
||||
assertThat(count).as("Expected count=1 now.").isEqualTo(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,7 +72,9 @@ public class ServletTestExecutionListenerTestNGIntegrationTests extends Abstract
|
|||
}
|
||||
|
||||
private void assertInjectedServletRequestEqualsRequestInRequestContextHolder() {
|
||||
assertThat(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()).as("Injected ServletRequest must be stored in the RequestContextHolder").isEqualTo(servletRequest);
|
||||
assertThat(((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest())
|
||||
.as("Injected ServletRequest must be stored in the RequestContextHolder")
|
||||
.isEqualTo(servletRequest);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -100,14 +100,16 @@ public class TestNGSpringContextWebTests extends AbstractTestNGSpringContextTest
|
|||
assertThat(webRequest).as("ServletWebRequest should have been autowired from the WAC.").isNotNull();
|
||||
|
||||
Object rootWac = mockServletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
|
||||
assertThat(rootWac).as("Root WAC must be stored in the ServletContext as: "
|
||||
+ WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).isNotNull();
|
||||
assertThat(rootWac)
|
||||
.as("Root WAC must be stored in the ServletContext as: " + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE)
|
||||
.isNotNull();
|
||||
assertThat(rootWac).as("test WAC and Root WAC in ServletContext must be the same object.").isSameAs(wac);
|
||||
assertThat(wac.getServletContext()).as("ServletContext instances must be the same object.").isSameAs(mockServletContext);
|
||||
assertThat(request.getServletContext()).as("ServletContext in the WAC and in the mock request").isSameAs(mockServletContext);
|
||||
|
||||
assertThat(mockServletContext.getRealPath("index.jsp")).as("Getting real path for ServletContext resource.").isEqualTo(new File("src/main/webapp/index.jsp").getCanonicalPath());
|
||||
|
||||
assertThat(mockServletContext.getRealPath("index.jsp"))
|
||||
.as("Getting real path for ServletContext resource.")
|
||||
.isEqualTo(new File("src/main/webapp/index.jsp").getCanonicalPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
<property name="id" value="bannedImports"/>
|
||||
<property name="regexp" value="true" />
|
||||
<property name="illegalClasses"
|
||||
value="^reactor\.core\.support\.Assert,^junit\.framework\..+,^org\.junit\.Assert$,^org\.junit\.Assume$,^org\.junit\.jupiter\.api\.Assertions$,^org\.junit\.Assert\.assertThat,^org\.junit\.Assume\.assumeThat,^org\.junit\.rules\.ExpectedException,^org\.slf4j\.LoggerFactory" />
|
||||
value="^reactor\.core\.support\.Assert,^junit\.framework\..+,^org\.junit\.Assert$,^org\.junit\.Assume$,^org\.junit\.jupiter\.api\.Assertions$,^org\.junit\.Assert\.assertThat,^org\.junit\.Assume\.assumeThat,^org\.testng\.Assert$,^org\.testng\.AssertJUnit$,^org\.junit\.rules\.ExpectedException,^org\.slf4j\.LoggerFactory" />
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
|
||||
<property name="id" value="bannedHamcrestImports"/>
|
||||
|
@ -194,6 +194,14 @@
|
|||
<property name="message" value="Please use AssertJ assertions." />
|
||||
<property name="ignoreComments" value="true" />
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
|
||||
<property name="id" value="testNGAssertions"/>
|
||||
<property name="maximum" value="0"/>
|
||||
<!-- should cover org.testng.Assert and org.testng.AssertJUnit -->
|
||||
<property name="format" value="org\.testng\.Assert(JUnit)?\.assert" />
|
||||
<property name="message" value="Please use AssertJ assertions." />
|
||||
<property name="ignoreComments" value="true" />
|
||||
</module>
|
||||
|
||||
<!-- Spring Conventions -->
|
||||
<module name="io.spring.javaformat.checkstyle.check.SpringLambdaCheck">
|
||||
|
|
Loading…
Reference in New Issue