I am new to writing test cases.
I need to test a part of a function that does not return anything.
It should be able to validate containsHello is true
or
check if a log error is obtained or not
public void Myfunction(x){
Boolean containsHello;
if (x != null) {
if ((x.contains(“hello"))
{
containsHello = true;
if (AppConfig.isWord()
&& (Secondclass.isSentence() && containsHello)) {
log.error("");
}
}
}
More code
}
Secondclass is a final class defined outside of the current .java file
AppConfig is also a class that exists outside the java file being tested.
How to run a test for the above code using Mockito. I tried the below code But does not work:
#Test
public void TestingmyFunction() throws Exception {
String x=“hello"
Mockito.when(Secondclass.isSentence()).thenReturn(true);
Mockito.when(AppConfig.isWord()).thenReturn(true);
Myfunction(x);
}
But I am not able to access the AppConfig.isWord() or Secondclass.isSentence()
Tried with powerMockito which throws this error:
java.lang.IllegalStateException: Failed to transform class with name com.amazon.alfred.cli.action.DeployBundleTests. Reason: javassist.bytecode.InterfaceMethodrefInfo cannot be cast to javassist.bytecode.MethodrefInfo
#Test
public void TestingmyFunction() throws Exception {
String x=“hello"
PowerMockito.mockStatic(Secondclass.class)
PowerMockito.when(Secondclass.isSentence()).thenReturn(true);
PowerMockito.mockStatic(AppConfig.class);
PowerMockito.when(AppConfig.isWord()).thenReturn(true);
Myfunction(x);
}
Related
I have to unit test the below method, whereas all the lines of this code related to third party aws library. The method also returns nothing. So only test I can do is verifying the exception. Any other test can I do to improve the code coverage?
public void multipartUpload() throws InterruptedException {
TransferManager tm = TransferManagerBuilder.standard()
.withS3Client(s3Client)
.withMultipartUploadThreshold(1024l)
.build();
PutObjectRequest request = new PutObjectRequest(bucketName, keyName, filePath);
Upload upload = tm.upload(request);
upload.waitForCompletion();
}
Let see the code that needs to be tested:
public class DemoCodeCoverage {
public void showDemo(LibraryCode library) {
System.out.println("Hello World!");
library.runDemoApplication();
// Extract the below code to a method since LibraryCode is not passed
// Then ignore running that method
// LibraryCode library = new LibraryCode()
// library.runDemoApplication_1();
// library.runDemoApplication_2();
// library.runDemoApplication_3();
System.out.println("World ends here!");
}
public boolean showBranchingDemo(boolean signal) {
if (signal) {
signalShown();
} else {
noSignal();
}
return signal;
}
public void signalShown() {
System.out.println("signalShown!");
}
public void noSignal() {
System.out.println("NoSignal!");
}
}
public class LibraryCode {
// Library can be AWS/Database code which needs authentication
// And this authentication is not a concern for our UT
// Still will end up execption when we do our UT
public void runDemoApplication() {
throw new RuntimeException();
}
}
Below can give good code coverage:
public class DemoCodeCoverageTest {
#Test
public void testShowDemo() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
LibraryCode lib = Mockito.mock(LibraryCode.class);
Mockito.doNothing().when(lib).runDemoApplication();
t.showDemo(lib);
// when(bloMock.doSomeStuff()).thenReturn(1);
// doReturn(1).when(bloMock).doSomeStuff();
}
#Test
public void testShowBranchingDemo() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
assertEquals(true, t.showBranchingDemo(true));
assertEquals(false, t.showBranchingDemo(false));
}
#Test
public void testSignalShown() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
t.showBranchingDemo(true);
Mockito.verify(t, times(1)).signalShown();
}
#Test
public void testNoSignal() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
t.showBranchingDemo(false);
Mockito.verify(t, times(1)).noSignal();
}
}
Below are the steps to increase the test code coverage:
Case_1: Testing void method
Assume you have method the does not take any params and return nothing.
public void printHelloWorld() {
System.out.println("Hello World")
}
Still you can write test that calls this method and returns successfully without any runtimeException.
Actually we haven't tested anything here other than giving a option to run the code by our tests. Thus increase the code coverage.
Additionally you can verify the invocation:
Mockito.verify(instance, times(1)).printHelloWorld();
There are circumstances you cannot test those, example say it is third party library call, then the library might have tested already, we just need to run through it.
#Test
public void testPrintHelloWorld() {
// may be hibernate call/other 3rd party method call
instance.printHelloWorld();
}
If your tool is not strict for 100% code coverage, you can even ignore it and justify it.
Case_2: Testing a method with object created and called another method inside the testing method
Assume you have method the does call DB to add entry in Hello_World table also prints it in console like below.
public void printHelloWorld() throws DBException {
DBConnection db = new DBConnection();
db.createEntry(TABLE_NAME, "Hello World");
System.out.println("Hello World")
}
You can extract those db code into new method, then test it separately.
public void printHelloWorld() throws DBException {
makeHelloWorldEntryInTable();
System.out.println("Hello World")
}
public void makeHelloWorldEntryInTable() throws DBException {
DBConnection db = new DBConnection();
db.createEntry(TABLE_NAME, "Hello World");
}
While testing with DB you would expect the DBConnectionException as it is just unit test. So one test with #Test(expected=DBException) for makeHelloWorldEntryInTable, and another test on printHelloWorld() with skipping the method makeHelloWorldEntryInTable call like below. Thus increases the code coverage.
#Test(expected=DBException)
public void testMakeHelloWorldEntryInTable() {
//This can any third party library which cannot be configured for ut.
//One example is testing the AWS bucket exist or not.
instance.makeHelloWorldEntryInTable();
}
#Test
public void testPrintHelloWorld() {
Mockito.doNothing()
.when(localInstance)
.makeHelloWorldEntryInTable();
localInstance.printHelloWorld();
}
Case_3: if you have private method, then make it default package level and test it. Thus improves the code coverage.
How can I test assertion immediately following an exception with EasyMock?
For example, there is a method storeIntoFile() which retrieves an object and writes it into a file. In case of an exception, this file is deleted. I'm looking to test this method specifically to verify that the file gets deleted on encountering an exception.
I have the following test to do this:
#Test (expected IOException.class)
public void testConnectionFailure throws IOException {
File storeFile = File.createTempFile(
"test",
"test"
);
storeIntoFile(storeFile);
Assert.assertFalse(storeFile.exists());
}
However in this case, the test completes as soon as the exception is encountered during the storeIntoFile call and does not proceed to test the following assertion. How can I test this assertion after the exception without using mock objects?
It's more a JUnit question than EasyMock. With JUnit 4.13, you can do the following.
public class MyTest {
public interface FileRepository {
void store(File file) throws IOException;
}
private void storeIntoFile(File file) throws IOException {
try {
repository.store(file);
} catch(IOException e) {
file.delete();
throw e;
}
}
private final FileRepository repository = mock(FileRepository.class);
#Test
public void testConnectionFailure() throws IOException {
File storeFile = File.createTempFile("test", "test");
IOException expected = new IOException("the exception");
repository.store(storeFile);
expectLastCall().andThrow(expected);
replay(repository);
IOException actual = assertThrows(IOException.class, () -> storeIntoFile(storeFile));
assertSame(expected, actual);
assertFalse(storeFile.exists());
}
}
I do not recommend the expected exceptions. assertThrows is much better since it allows to assert on the exception.
I have added a test case in my Spring Boot application. However, when I ./gradlew build, all the test cases pass. Any reason?
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertThat(!thrown);
}
It's because your test doesn't test anything.
Try this :
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertTrue(!thrown);
}
you can try something like the following (in case you want to use the assertThat method):
#Test
public void testIntentionalError() throws Exception {
boolean thrown = true;
assertThat(!thrown, is(true));
}
using hamcrest matcher (import static org.hamcrest.core.Is.is)
This question already has answers here:
How to continue test after JUnit ExpectedException if thrown?
(4 answers)
Closed 6 years ago.
In my Android project I want to test, with the same #Test, a class which can throw several times the same exception with different messages.
I want my test to pass for a given list of messages and to fail for others.
Making some research on Junit I tried to implement this using #Rule, expectMessage() and Hamcrest matcher.
My implementation is currently based on the "Custom matcher" described here.
#RunWith(AndroidJUnit4.class)
public class TestException extends ApplicationTestCase {
#Rule public ExpectedException thrown= ExpectedException.none();
public TestException(){
super(AplicatyApplication.class);
}
#Test
public void testException() throws Exception {
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage(new MatchesPattern("*"));
Dummy.exec(0);
// do more stuff here ...
Dummy.exec(1);
// ...
Dummy.exec(2);
// ...
Dummy.exec(3); // I want my test to fail here
// ...
}
class MatchesPattern extends TypeSafeMatcher<String> {
private String pattern;
public MatchesPattern(String pattern) {
this.pattern = pattern;
}
#Override
protected boolean matchesSafely(String item) {
return item.matches(pattern)
&&
item.startsWith("My message")
&& (
item.endsWith("1")
||
item.endsWith("2")
);
}
#Override
public void describeTo(Description description) {
description.appendText("matches pattern ").appendValue(pattern);
}
#Override
protected void describeMismatchSafely(String item, Description mismatchDescription) {
mismatchDescription.appendText("does not match");
}
}
static class Dummy {
static void exec(int i){
if(i == 0)
return;
if(i == 1)
throw new IndexOutOfBoundsException("My message1");
if(i == 2)
throw new IndexOutOfBoundsException("My message2");
if(i == 3)
throw new IndexOutOfBoundsException("My message3");
}
}
}
Running this test I can see that the matcher is called just once, executing Dummy.exec(1);.
The matchesSafely(String item) returns true and the the test ends with the status Passed.
All this seems to be Okay, with my understanding of the #Rule. I was waiting an exception : I got it; I was waiting a given message : I got it.
I can not find a way to continue the execution of my test once the first exception has been thrown.
My questions are :
Is it possible to use #Rule to check more than one exception thrown into one tested method, or do I have to use the typical try/catch testing the exception message in every catch block?.
Is there another/more elegant way to test this type of concerns.
I suggest to split the test method into multiple tests, one for each requirement.
#Test
public void testException_1() throws Exception {
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("My message1");
Dummy.exec(1);
}
In case it needs to be in one test method, I would build it with try-catch and ErrorCollector.
#Test
public void testException_1() throws Exception {
try {
Dummy.exec(1);
fail();
} catch (IndexOutOfBoundsException e) {
errorCollector.checkThat(e.getMessage(), is("My message1"));
}
try {
Dummy.exec(2);
...
} ...
}
I would try to avoid to build a custom Matcher.
I wrote unit test (JUnit 4) that performs some logic and writes result to file. In #Before annotated method it creates file and in #After the file should be deleted. It isn't though, and I can't figure it out, why.
I am using Google Guava 10.01 Files API. Here's my unit test code:
public class CashierTest extends ContextedTest {
private File cashierFile;
#Before
public void createFile() throws Exception {
cashierFile = new File("D://workspace-sts/spring-miso/cashier.txt");
cashierFile.createNewFile();
}
#After
public void release() {
if (cashierFile.exists()) {
if (!cashierFile.delete()) {
System.out.println("Couldn't delete cashier file");
}
}
cashierFile = null;
}
#Test
public void testCashier() throws Exception {
// file shouldn't contain any text
assertFalse(Files.toString(cashierFile, Charset.defaultCharset()).length() > 0);
Cashier cashier = (Cashier) context.getBean("cashier");
ShoppingCart cart = (ShoppingCart) context.getBean("shoppingCartPrototype");
cashier.checkout(cart);
assertTrue(cashierFile.exists());
// file should contain text now
assertTrue(Files.toString(cashierFile, Charset.defaultCharset()).length() > 0);
}
#Override
protected void setPath() {
path = "sk/xorty/advancedioc/beans.xml";
}
}
Note: ContextedTest superclass is my test which holds Spring container it isn't relevant atm.
Simply instanting a File does not mean that an actual file will be created. Call createNewFile() or createTempFile() on that instance for this.
Within your test method you don't seem to pass that file reference to anyone that could possibly create the file or write anything in it... Am I missing something or is the code you posted missing some key lines ?
You should use the TemporaryFolder Rule with JUnit 4. This will handle the setup and teardown of temporary test directories and files.
public static class HasTempFolder {
#Rule public TemporaryFolder folder= new TemporaryFolder();
#Test public void testUsingTempFolder() throws IOException {
File createdFile= folder.newFile("myfile.txt");
...
}
}
Other Rules are part also part of Junit 4.