I have a jhipster application that runs fine but I can't unit test it. It is configured to use mysql for development and production. I have updated the schema a few times (imported jdl) and used liquibase changelogs to keep it happy. I have added some functionality to the service layer and want to test it to ensure it behaves as expected. But when I run the unit test I am running into problems with liquibase. It complains about a "missing column [material_template_id] in table [dimension]" which by all accounts should be there. The entity dimension file has the column defined:
<column name="material_template_id" type="bigint">
<constraints nullable="true" />
</column>
I have defined the unit test like this:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = AlphaApp.class)
#Transactional
public class BomMaterialLineServiceImplTest {
#Autowired
BomMaterialLineServiceImpl bomLineSvc;
#Before
public void setUp() throws Exception {
}
#After
public void tearDown() throws Exception {
}
#Test
public void findBomMaterialLinesForBOM() {
}
}
AlphaApp is the main file and is annotated as follows:
#ComponentScan
#EnableAutoConfiguration(exclude = {MetricFilterAutoConfiguration.class, MetricRepositoryAutoConfiguration.class})
#EnableConfigurationProperties({LiquibaseProperties.class, ApplicationProperties.class})
public class AlphaApp {
I have tried disabling liquibase in the test config file. Is there a standard way of implementing these tests with jhipster? It looks to me like the unit test is configured to use an in memory database as standard - is it this that is causing me grief?
Yes unit tests in JHipster use H2 but you can change it by editing src/test/resources/config/application.yml and changing datasource properties.
You can use testcontainers as explained in this article written by a JHipster team member.
Related
I'm attempting to set up some Spring Boot JPA tests using:
package biz.ianw.coindatabase.test;
#RunWith(SpringRunner.class)
#DataJpaTest
public class DbTests {
#Test
public void test1() { ... }
}
I have a service class:
package biz.ianw.coindatabase.database;
//#Service
#Repository
#Transactional(readOnly=false)
public class CoinDbService { ... }
and an application:
package biz.ianw.coindatabase;
#SpringBootApplication
#Slf4j
#Configuration
#EnableEncryptableProperties
public class Main {
#Autowired
CoinDbService dbService;
... }
Starting the test gives the error:
Field dbService in biz.ianw.coindatabase.Main required a bean of type 'biz.ianw.coindatabase.database.CoinDbService' that could not be found.
This is, I assumed, something to do with the type of beans #DataJpaTest loads during startup:
#DataJpaTest can be used if you want to test JPA applications. By
default it will configure an in-memory embedded database, scan for
#Entity classes and configure Spring Data JPA repositories. Regular
#Component beans will not be loaded into the ApplicationContext.
I'm not quite sure why #Service classes should be considered as not required for JPA testing, but I tried to force the matter by annotating it as #Repository instead, but to no avail.
I can manually load the class with #Import(...) but it seems a tad hooky. Is there a better way to tell DataJpaTest what I need for testing?
I am quoting from DataJpaTest documentation where you can find the answer to your question.
Annotation that can be used in combination with
#RunWith(SpringRunner.class) for a typical JPA test. Can be used when
a test focuses only on JPA components.
Using this annotation will disable full auto-configuration and instead
apply only configuration relevant to JPA tests.
By default, tests annotated with #DataJpaTest will use an embedded
in-memory database (replacing any explicit or usually auto-configured
DataSource). The #AutoConfigureTestDatabase annotation can be used to
override these settings.
If you are looking to load your full application configuration, but
use an embedded database, you should consider #SpringBootTest combined
with #AutoConfigureTestDatabase rather than this annotation.
I'm porting an app across from JDBC / REST to spring-data-rest and my one and only unit test with fails with the error
NoSuchBeanDefinitionException:
No qualifying bean of type 'com.xxx.repository.ForecastRepository' available
The app was retro-fitted with spring-boot just previously, and now I'm trying to put a new layer in place with spring-data-rest on top of spring-data-jpa.
I'm attempting to work out the correct Java-config according to
Custom Test Slice with Spring Boot 1.4
but I had to deviate from the idiomatic approach because
the #WebMvcTest annotation doesn't suppress the security module which causes the test to fail
the #MockMvcAutoConfiguration fails due to missing dependencies unless I specify #SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK) (see here)
#WebMvcTest and #SpringBootTest are mutually exclusive since they both specify #BootstrapWith and can't run together
So this is the closest I've got but Spring can't locate my #RepositoryRestResource repository:
Repository
#RepositoryRestResource(collectionResourceRel = "forecasts", path = "forecasts")
public interface ForecastRepository extends CrudRepository<ForecastExEncoded,
Long> {
JUnit Test
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK,
classes = {TestRestConfiguration.class})
public class ForecastRestTests {
#Autowired
private MockMvc mockMvc;
#Autowired
private ForecastRepository forecastRepository;
#Before
public void deleteAllBeforeTests() throws Exception {
forecastRepository.deleteAll();
}
#Test
public void shouldReturnRepositoryIndex() throws Exception {
mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
jsonPath("$._links.forecasts").exists());
}
}
Configuration
#OverrideAutoConfiguration(enabled = false)
#ImportAutoConfiguration(value = {
RepositoryRestMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
WebMvcAutoConfiguration.class,
MockMvcAutoConfiguration.class,
MockMvcSecurityAutoConfiguration.class
})
#Import({PropertySpringConfig.class})
public class TestRestConfiguration {}
Also tried...
I tried to configure the unit test with just #WebMvcTest and this #ComponentScan below from How to exclude AutoConfiguration from Spring Boot), in an attempt to simplify it all, however the excludeFilters had no effect.
#ComponentScan(
basePackages="com.xxx",
excludeFilters = {
#ComponentScan.Filter(type = ASSIGNABLE_TYPE,
value = {
SpringBootWebApplication.class,
JpaDataConfiguration.class,
SecurityConfig.class
})
})
I've set Spring's logging to trace because all I can do at this point is try to find clues as to what is happening from log output. So far though without any luck.
I can see in the logging that RepositoryRestConfiguration is loading, but obviously it isn't fed with the right info and I am unable to work out how that is done, after googling and pouring over the Spring docs and API. I think I must have read every relevant question here on SO .
Update 2016-11-16 10:00
One thing I see in the logs which concerns me is this:
Performing dependency injection for test context [DefaultTestContext#2b4a2ec7 [snip...]
classes = '{class com.xxx.TestRestConfiguration,
class com.xxx.TestRestConfiguration}',
i.e. the context lists the configuration class twice. I specified the config class (once only) on the #SpringBootTest#classes annotation. But if I leave off the #classes from the annotation, Spring Boot finds and pulls in all the config via the #SpringBootApplication class.
So is that a hint that I am specifying the configuration in the wrong place? How else would I do it?
After way too much time, I settled on this approach.
Custom Test Slice with Spring Boot 1.4 looked promising but I couldn't get anywhere with it.
While going over and over
Accessing JPA Data with REST
I realised I had to include the JPA setup because spring-data-rest is using them directly - no chance to mock them or run unit tests without an embedded database.
At least not as far as I understand it. Maybe it is possible to mock them and have spring-data-rest run on the mocks against test data, but I think spring-data-rest and spring-data are probably too tightly coupled.
So integration testing it must be.
In the Spring source code provided with the articles above
gs-accessing-data-rest/ApplicationTests.java
the logging shows Spring Boot pulling in the whole configuration for the application context.
So that my SpringBootApplication class is avoided and the security module isn't loaded up, I set up my tests like this:
#RunWith(SpringRunner.class)
#SpringBootTest
#ContextConfiguration(classes = {
JpaDataConfiguration.class,
TestJpaConfiguration.class,
TestRestConfiguration.class,
PropertySpringConfig.class})
public class ForecastRestTests {
#SuppressWarnings("SpringJavaAutowiringInspection")
#Autowired
private MockMvc mockMvc;
#Autowired
private ForecastRepository forecastRepository;
#Before
public void deleteAllBeforeTests() throws Exception {
forecastRepository.deleteAll();
}
#Test
public void shouldReturnRepositoryIndex() throws Exception {
mockMvc.perform(get("/")).andDo(print()).andExpect(status().isOk()).andExpect(
jsonPath("$._links.forecasts").exists());
}
}
with these configuration classes:
#Configuration
#EnableJpaRepositories(basePackages = {"com.bp.gis.tardis.repository"})
#EntityScan(basePackages = {"com.bp.gis.tardis.type"})
public class JpaDataConfiguration {
and
#Configuration
#OverrideAutoConfiguration(enabled = false)
#ImportAutoConfiguration(value = {
CacheAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
TransactionAutoConfiguration.class,
TestDatabaseAutoConfiguration.class,
TestEntityManagerAutoConfiguration.class })
public class TestJpaConfiguration {}
and
#Configuration
#OverrideAutoConfiguration(enabled = false)
#ImportAutoConfiguration(value = {
RepositoryRestMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
WebMvcAutoConfiguration.class,
MockMvcAutoConfiguration.class,
MockMvcSecurityAutoConfiguration.class
})
public class TestRestConfiguration {}
so the TL;DR summary is: use #ContextConfiguration to specify the configuration files that specify #OverrideAutoConfiguration and #ImportAutoConfiguration
Hi I'm trying to test my Service and Dao layers for a Java EE 7 application.
So I looking for testing solutions follow tutorials using Arquillian with junit test and wildfly remote dependence.
Dao and Service interfaces with relative implementations have been created, following my junit test with Arquillian:
#RunWith(Arquillian.class)
public class GenericServiceTest {
#Inject
private EmployeeService employeeService;
#Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap
.create(JavaArchive.class)
.addAsManifestResource("META-INF/persistence.xml",
"persistence.xml")
.addClasses(EmployeeDao.class, EmployeeDaoImpl.class,
EmployeeService.class, EmployeeServiceImpl.class,
Employee.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
}
#Test
#Transactional
public void should_crud() {
// Gets all the objects
assertNotNull(employeeService);
Employee employee = employeeService.get(new Integer(1));
assertNotNull(employee);
}
}
Running class as JUnit Test it doesn't work with this error:
Caused by: java.lang.Exception: "WFLYCTL0216: Management resource '[(\"deployment\" => \"test.war\")]' not found"
Test pass if any classes has been added to ShrinkWrap as following:
#RunWith(Arquillian.class)
public class GenericDaoTest {
#Inject
private EmployeeService employeeService;
#Deployment
public static JavaArchive createTestableDeployment() {
final JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
return jar;
}
#Test
public void should_crud() {
}
}
How can I create a working test using arquillian for Java EE 7 adding service class implementations?
And I have To add every Class and Intefaces that have to be called (for example all entities,dao etc classes) or only Service Interface and implementation Class?
Thanks a lot
Since you're developing a javaee application, I would suggest you to create a War archive instead of Jar.
You can add the whole package using
ShrinkWrap.addPackages(true, "com.yourpackage.name") so you don't have to add your classes independently.
If I understand the question correctly you want to test a war archive.
If this is the case you should change
return ShrinkWrap
.create(JavaArchive.class)
to
return ShrinkWrap
.create(WarArchive.class)
In addition you should add your persistence.xml file to the META-INF folder like:
.addAsResource("test-persistence.xml", "META-INF/persistence.xml")
If you want to use the annotation #Transactional in your tests, you need to add a few dependencies to your test scope. If you didn't add them yet you can read at http://arquillian.org/modules/transaction-extension/ what dependencies to add.
I am using play framework activator and my tests are mostly running fake application with in memoory database (EBean ORM).
The tests are failing once to ~5 times with attached error which does not explain the reason and specific test name.
anyone familiar with this issue?
Failing test case:
public class ApplicationTest {
#Test
public void renderTemplate() {
Content html = views.html.index.render("Your new application is ready.");
assertEquals("text/html", contentType(html));
assertTrue(contentAsString(html).contains("Your new application is ready."));
}
}
Can anyone tell me how get mbunit to run more than one test at a time without it setting up and tearing down after every test?
Currently I'm using selenium for UI testing and need to run the tests consecutively do a login page.
Thanks in advance,
cb
Are you looking for FixtureSetUp/FixtureTearDown attribute [used to be called TestFixtureSetUp], which is called at class level, meaning, it will be set up once for all the tests in one test class.
Setup/TearDown attribute is called on Method level.
MbUnit also support test assembly setup and teardown. Here is a link for this.
[assembly: AssemblyCleanUp(typeof(AssemblyCleaner))]
...
public class AssemblyCleaner
{
[SetUp]
public static void SetUp()
{
Console.WriteLine("Setting up {0}", typeof(AssemblyCleanUp).Assembly.FullName);
}
[TearDown]
public static void TearDown()
{
Console.WriteLine("Cleaning up {0}", typeof(AssemblyCleanUp).Assembly.FullName);
}
}