I have the following code:
try {
em.persist(myObject);
em.flush();
}
catch (Exception e) {
System.out.println("An Exception occur when trying to persist and flush");
}
In test I have mock my EntityManager with Mockito:
#Mock
EntityManager mockEm;
but as persist and flush are void methods, I'm not able able to write something like:
when(mockEm.persist(anObject).then(doSomeThing);
How can I write unit testing (with JUnit)to mock em.persist and em.flush in order to test both cases with and without exception?
Thanks.
I guess we need more details. For now, you can do something like this: (it's kind of pseudo-code).
#Test // it passess when there's one object in repository (I assume u have clean memory db)
public void shouldPersistMyObject() throws Exception {
em.persist(myObject);
em.flush();
Assert.assertThat(dao.findAll(), Matchers.equalTo(1));
}
#Test(expected = <YourDesiredException>.class) // if <YourDesiredException> is thrown, your test passes
public void shouldThrowExceptionWhenSavingCorruptedData() {
//set NULL on some #NotNull value, then save, like:
myObject.setUserId(null);
em.save(myObject); //exception is thrown
}
Related
I want to call different methods that interact with my database in one method.
something like this :
#Autowired
EnteteService es; // service for jpaRepository
#Autowired
SystemOracleServiceJpa so; // service using jdbcTemplate
#Autowired
DetailService ds; // service for jpaRepository
#Transactional
public void configure(EnteteAR entete) throws ConfigurationException {
try{
this.es.save(entete); // first methode
List<DetailAR> details = this.so.getStructure(entete.getTableName());
if(details.size()>0){
this.ds.saveAllDetails(details); // second
this.so.CreateTable(details, entete.getTableName(), "DEM");//third
this.so.createPkIdxDem(entete.getTableName()); // fourth
this.so.CreateTable(details, entete.getTableName(), "BACK"); // fifth
}
else{
throw new ConfigurationException("Configuration error");
}
}catch(Exception e){
throw new ConfigurationException(e.getMessage());
}
}
I want to commit only if no errors appears in all this methods inside my main method "configure".
I was thinking that #transactionnal annotation work for this, but that commit after each method inside.
Exemple :
if this.es.save work and this.ds.saveAllDetails dont, I find data of es.save on database :(
Someone can help my please ?
thank with advance for your reading and your potential help.
#Transactional will automatically invoke a rollback if an unchecked exception is thrown from the executed method.
ConfigurationException in your case is a checked exception and hence it does not work.
You can make it work by modifying your annotation to
#Transactional(rollbackOn = ConfigurationException.class)
public void configure(EnteteAR entete) throws ConfigurationException {
try{ ....
I have a method which has the following code in it, it saves a order object to the orderStatus jpa repository and i have a try catch method which should capture the JDBC Connection exception.
How do i test this scenario using Junit and mockito?
try {
orderStatusRepository.save(newOrderStatus);
} catch (JDBCConnectionException ex) {
);
If the code is the goal is to test that in case JDBCConnectionException is thrown it is caught and not propagated I would suggest to mock orderStatusRepository using Mockito:
when(orderStatusRepository.save(newOrderStatus))
.thenThrow(JDBCConnectionException.class);
then execute the test and check that the method returns normally and that mocked object method was accessed (the exception therefor was thrown):
verify(orderStatusRepository).save(newOrderStatus);
Note that if save method doesn't return anything you would need to mock it a bit differently:
doThrow(JDBCConnectionException.class)
.when(orderStatusRepository).save(newOrderStatus);
follow the below code to test your code for the JDBC connection exception.
#MockBean
private OrderStatusRepository orderStatusRepository;
#Test
public void jdbcConnectionExceptionTest() {
try{
when(orderStatusRepository.save(newOrderStatus))
.thenThrow(JDBCConnectionException.class);
orderStatusRepository.save(newOrderStatus);
} catch (Exception e) {
assertTrue(e instanceof JDBCConnectionException);
}
}
Below is the piece of code. Now already the exception is caught. How can I write the negative test for the same? To make sure code enters in catch block?
public ThirdPartyResponse load(ThirdPartyRequestContext context) {
ThirdPartyResponse thirdPartyResponse = new ThirdPartyResponse();
try
{
thirdPartyResponse.setData(getData(context));
}catch (Exception e)
{
LOGGER.error("Error executing {}", context.getEndpoint(), e);
thirdPartyResponse.setData(Collections.emptyList());
thirdPartyResponse.setErrorMessage(e.getMessage());
}
return thirdPartyResponse;
}
You can assert that error message is not null for the thirdPartyResponse object that's returned from your method:
assertNotNull(thirdPartyResponse.getErrorMessage());
import statement:
import static org.junit.Assert.assertNotNull;
// mock context so that getData(context) throws exception with message "foo"
...
ThirdPartyResponse response = load(context);
assertThat(response.getMessage(), is("foo"));
1st of all , don't try to catch main "Exception" in catch as it will catch all kind of exception which you may not even want to catch. Next, if you want to write test case for that you need to use Mockito for performing that negative test, you need to write something like this
Mockito.when(some_method(anyparam())).thenThrow(new YourCustomException("error message"));
probably you may need to mock inside getData() method.
As you are using mockito try following:
1) Alter the load method so that the thirdPartyResponse is a protected method call:
public ThirdPartyResponse load(ThirdPartyRequestContext context) {
ThirdPartyResponse thirdPartyResponse = createThirdPartyResponse();
2) Put creation of that object inside the createThirdPartyResponse():
protected ThirdPartyResponse createThirdPartyResponse(){
return new ThirdPartyResponse();
}
3) Spy on the SUT and mock the createThirdPartyResponse method:
public class ClassUnderTest{
#Spy
ClassUnderTest classUnderTestSpy;
#Spy
ThirdPartyResponse thirdPartyResponseSpy;
#BeforeClass
public void init(){
MockitoAnnotations.initMocks(this);
}
public void expectExceptionOnLoad(){
// Arrange
Mockito.doThrow(new Exception()).when(thirdPartyResponseMock.setData(Mockito.any(Object.class));
Mockito.doReturn(thirdPartyResponseSpy).when(classUnderTestSpy).createThirdPartyResponse();
// Act
classUnderTestSpy.load(context);
// Assert
assertNotNull(thirdPartyResponseSpy.getErrorMessage());
}
}
PS. you need to replace the Mockito.any(Object.class) with a adequate class
Let's say I test a class method that is reliant on another method that we do not want or can not test directly, which handles a checked exception, in the following manner:
public class A {
public void process(){
if (isProcessingSuccessful()){
LOG.info("Success");
}
else {
LOG.error("Fail");
}
}
private boolean isProcessingSuccessful(){
try{
doSomeOtherStuff();
return true;
}
catch (Exception e){
return false;
}
}
}
Now, if I have a test class testing for the A#process(), like:
#Test
public void shouldFailDueToCommandGatewayError() {
A a = new A();
// setting up preconditions
//testing here
a.process();
//Now, assert exception was thrown during the course of a.process() execution, something like
exception.expect(NullPointerException.class);
// ?? how to do that?
}
TLTD: It is possible to write separate test for isProcessingSuccessful() or do something similar, but let's say that method is not accessible for testing, like it's private in a library?
Given the above constraints, is there any way to write a test in a way that ascertains the exception was thrown in the underlying method as above?
No, junit can't tell the exception was thrown, since it gets eaten by the code being tested. For you to detect what happened here you would have to check what was written to the log. Replace the appender with something that holds onto what is written to it, then the test can verify what was written to it at the end of the test.
You can't catch the exception again which have been already consumed. The only way is to catch the exception with the test method as described below.
Annote the test method that is supposed to fail with #Test and use the expected parameter for the expected exception.
#Test(expected = NullPointerException.class)
public void shouldFailDueToCommandGatewayError() {
// something that throws NullPointerException
}
#Test(expected = NullPointerException.class)
This basically says:
If this test quits with a NullPointerException then everything is as expected. Otherwise this test will fail.
#Test(expected = NullPointerException.class)
has been mentioned already. This feature came wuth JUnit 4. Before that and if you want to do want to check more than just a particular type of exception being thrown, you can do something like this:
try {
doSometing("", "");
fail("exception expected");
}
catch(IllegalArgumentException iae) {
assertEquals("check message", "parameter a must not be empty", iae.getMessage());
assertNull("check non-existance of cause", iae.getCause());
}
try {
doSometing("someval", "");
fail("exception expected");
}
catch(IllegalArgumentException iae) {
assertEquals("check message", "parameter b must not be empty", iae.getMessage());
assertNull("check non-existance of cause", iae.getCause());
}
This is particular useful if the same type of exception is thrown and you want to ensure that the "correct" exception is thrown with a given combination of parameters.
I am trying to test file manipulation with my APP. First of all I wanna check that whenever I call a function that reads the file, this function will throw an Exception because the file isn't there.
However, I don't seem to understand how to achieve this... This is the code I designed, but it doesn't run ... the normal JUNIT says the FILEPATH wasn't found, the android JUNIT says, the Test could not be run.
The folder: /data/data/example.triage/files/ is already available in the virtual device...
#Before
public void setUp() throws Exception {
dr = new DataReader();
dw = new DataWriter();
DefaultValues.file_path_folder = "/data/data/example.triage/files/";
}
#After
public void tearDown() throws Exception {
dr = null;
dw = null;
// Remove the patients file we may create in a test.
dr.removeFile(DefaultValues.patients_file_path);
}
#Test
public void readHealthCardsNonExistentPatientsFile() {
try {
List<String> healthcards = dr.getHealthCardsofPatients();
fail("The method didn't generate an Exception when the file wasn't found.");
} catch (Exception e) {
assertTrue(e.getClass().equals(FileNotFoundException.class));
}
}
It doesn't look like you are checking for the exception in a way that correlates with the JUnit API.
Have you tried to make the call:
#Test (expected = Exception.class)
public void tearDown() {
// code that throws an exception
}
I don't think you want the setup() function to be able to generate an exception, since it is called before all other test cases.
Here's another way to test exceptions:
Exception occurred = null;
try
{
// Some action that is intended to produce an exception
}
catch (Exception exception)
{
occurred = exception;
}
assertNotNull(occurred);
assertTrue(occurred instanceof /* desired exception type */);
assertEquals(/* expected message */, occurred.getMessage());
So I would make you setup() code not throw an exception and move the exception generating code to a test method, using an appropriate way to test for it.