/*
this method will create the required manifest file in compatible format such that
quicksight can import data from specified s3 bucket
*/
private JSONObject CreateManifestFileJSONObject(JSONObject ManifestFile){
JSONArray URIPrefixArray= new JSONArray();
URIPrefixArray.put(PrefixLocation);
JSONObject URIPrefixJSONObject= new JSONObject();
URIPrefixJSONObject.put("URIPrefixes",URIPrefixArray);
JSONArray FileLocationsArray= new JSONArray();
FileLocationsArray.put(URIPrefixJSONObject);
JSONObject globalUploadSettings= new JSONObject();
globalUploadSettings.put("format","JSON");
ManifestFile.put("globalUploadSettings",globalUploadSettings);
ManifestFile.put("fileLocations",FileLocationsArray);
return(ManifestFile);
}
/*
this method will upload the ManifestFile to same S3 Bucket in which data files is stored
*/
private void UploadManifestFileJSONObjectToS3(JSONObject ManifestFile){
try {
AmazonS3 S3Client = new Utility().SetUpS3Client();
byte[] fileContentBytes = (ManifestFile.toString()).getBytes();
InputStream fileInputStream = new ByteArrayInputStream(fileContentBytes);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(fileContentBytes.length);
S3Client.putObject(new PutObjectRequest(Bucket_Name, ManifestFileName, fileInputStream, objectMetadata).withCannedAcl(CannedAccessControlList.PublicRead));
}
catch(Exception exception){
exception.printStackTrace();
}
}
public void handler() {
System.out.println("inside the manifest file");
try {
JSONObject ManifestFile = new JSONObject();
ManifestFile = CreateManifestFileJSONObject(ManifestFile);
UploadManifestFileJSONObjectToS3(ManifestFile);
}
catch(Exception exception){
exception.printStackTrace();
}
I want to test handler method but handlor method is calling private methods so I do not know how to write the test class for this code.
i want to write unit test for this class please help
this is the test class I am able to create up to this point but it will not surely mock s3 behaviour
#Test
public void handler() {
ManifestFileHandler manifestFileHandler=new ManifestFileHandler();
manifestFileHandler.handler();
}
You can test private methods with the help of PowerMock provides utilities which uses reflection to do certain things.
check the below example,
https://examples.javacodegeeks.com/core-java/mockito/mockito-mock-private-method-example-with-powermock/
There are two schools of thought on unit testing private functions. The first is that you make them public (or protected or package accessible) and test them as you would a public function. The second is that if they are private they are part of the encapsulated implementation detail and you only need to test them through the public functions.
My personal view is that complicated private functions are often a sign that you are breaking the single responsibility principle and it's likely you should have logic in private functions that should be split into a separate class that can then be tested through its public methods.
With respect to the code you've posted you have a larger problem than how to test the private functions: your class depends on other classes that you don't have control over. You have no way of mocking the behaviour of those classes to test various scenarios or to verify that they have been called correctly. I suspect it is this problem that is really behind your question.
As an example, I would suggest you inject a S3Client into your class rather than create it internally through new Utility().SetUpS3Client(). That way you can mock its behaviour and verify it is called correctly by your code. Attempting to do that with the real version of this class will be challenging.
So using this model, your code might look something like:
public class ManifestFileHandler {
private final S3Client client;
public ManifestFileHandler(S3Client client) {
this.client = client;
}
private void upload(JSONObject manifestFile) {
...
client.putObject(...);
}
public void handleManifest() {
...
upload(manifestFile);
...
}
}
And your test code (using mockito):
#Test
void testManifestUpload() {
S3Client client = mock(S3Client.class);
ManifestFileHandler handler = new ManifestFileHandler(client);
handler.handleManifest();
verify(client).putObject(expectedObject);
}
If you need to capture the argument passed to putObject and assert various aspects of it then that is possible with most mocking tools (including mockito) but is beyond the scope of your question.
I am writting test for a try catch block, but I am quite confused about how to test the catch block...especially it uses slf4j to log the error.
addText here is the another method from the same class.
public class TextQueue {
public void addTextToQueue(final Text text) {
try {
if (text != null) {
addText(text);
}
} catch (final JsonProcessingException e) {
LOGGER.error("Error adding text to the queue : {}", e);
}
}
}
here is my test case
#RunWith(MockitoJUnitRunner.class)
public class TextQueueTest {
private org.slf4j.Logger LOGGER = LoggerFactory.getLogger(TextQueueTest.class);
private static final String MY_TEXT = "src/text.json";
private Text text;
private final ObjectMapper mapper = new JacksonConfig().dateAsStringObjectMapper();
#Mock
private TextQueue textQueue;
#Before
public void setUp() throws IOException {
text = mapper.readValue(new File(TextQueueTest.MY_TEXT), Text.class);
}
#Test
public void addTextToQueue() {
try{
textQueue = spy(textQueue);
textQueue.addTextToQueue(text);
}catch(final Exception e){
LOOGER.error("add text to queue threw an error" + e);
}
}
can anyone help me solve this problem?
First of all, you should really read a good tutorial about Mockito, like the one from vogella. You see, you are simply throwing together a lot of things that are non-sensical.
Like:
#Mock
private TextQueue textQueue;
to then have
textQueue = spy(textQueue);
within your test case. You should be really clear about this. A spy is build on a real instance of your class under test. Creating a spy that spies on a mock, as said: that makes no sense.
Then:
}catch(final Exception e){
Logger.error("add text to queue threw an error" + e);
Again, non-sensical. The whole idea of your unit tests is that they fail when something is wrong. When your production code throws unexpected exceptions, you don't log them, you just let them fail your test case in the end.
To answer the actual question: it looks like your production code is using a specific "constant" logger instance. Given that design, the only way to check your production code would be to:
make that LOGGER a mocked object
somehow inject it into an instance underTest of your production code class
trigger that method to test on underTest (and somehow force the method to throw an exception)
verify that the mocked LOGGER saw the expected call to error()
We can't give better advise, because your code input isn't sufficient, we don't really know what your production class is doing (for example: we don't know what LOGGER is, and where it is coming from. if it happens to be a static variable, then most likely, you can't get "control" over it with Mockito).
In any case, you probably actually need the spy concept. In order to test addTextToQueue() you need a way to invoke the "real" addTextToQueue() implementation, but the call to addTser() within needs to go to a mock (so that you can control what that call does).
But as said: start by really researching how Mockito works, instead of throwing together things that make no sense in some "trial and error" approach. Correct unit testing with mocking is complicated, you can't learn that by "trial and error".
I have a unit test (simplified version below) that tests a Netty handler.
I create an EmbeddedChannel with an instance of the handler.
The caller writes a string to the channel
The handler receives the string, reverses and writes it back.
The caller reads the return values from the channel and verifies it is the reverse of the sent string.
This works perfectly. However, I need to verify the number of invocations on the channel, so I created a spy of the channel but mocked no methods, since I don't want to change the behavior of the class, just count invocations.
Now the test fails. 2 of the assertions succeed. They are a test to make sure the handler was called, and a test to verify the number of times a method of the channel was called. However, the final read response is always null when the spy is used.
I was under the impression that a solitary spy with no other mocking would not affect the behavior of the spied object, but obviously it does. The [nonPower] Mockito docs indicate the objects are copied which might cause this issue, but the PowerMockito docs are not as specific.
I am using Netty 4.1.6.Final and Powermock 1.5.6.
UPDATE: I managed to get the test working but it's a bit of wonky workaround. See the new method testSpiedEmbeddedChannel2. The workaround is that I create a non-spied channel (ecx), then a the spied channel (ec) using ecx. I issued the write on ec, and the read using ecx. This means if I try to verify methods used in the read, they will not be counted.
Here's the code with the successful and failing tests.
#RunWith(PowerMockRunner.class)
#PowerMockIgnore({"javax.management.*"})
#PrepareForTest(EmbeddedChannel.class)
public class TestEmbeddedChannel {
class EchoHandler extends ChannelDuplexHandler {
final AtomicInteger reads = new AtomicInteger(0);
#Override
public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
reads.incrementAndGet();
final String value = (String)msg;
final String response = new StringBuilder(value).reverse().toString();
ctx.channel().writeAndFlush(response);
}
}
#Test
public void testEmbeddedChannel() { // PASSES
final EchoHandler handler = new EchoHandler();
final EmbeddedChannel ec = new EmbeddedChannel(handler);
ec.writeInbound("Hello World");
final String response = ec.readOutbound();
Assert.assertEquals(1, handler.reads.get());
Assert.assertEquals("dlroW olleH", response);
}
#Test
public void testSpiedEmbeddedChannel() { // FAILS
final EchoHandler handler = new EchoHandler();
final EmbeddedChannel ec = spy(new EmbeddedChannel(handler));
ec.writeInbound("Hello World");
final String response = ec.readOutbound();
verify(ec, times(2)).isOpen(); // OK
Assert.assertEquals(1, handler.reads.get()); // OK
Assert.assertEquals("dlroW olleH", response); // FAILS
}
#Test
public void testSpiedEmbeddedChannel2() { // PASSES
final EchoHandler handler = new EchoHandler();
final EmbeddedChannel ecx = new EmbeddedChannel(handler);
final EmbeddedChannel ec = spy(ecx);
ec.writeInbound("Hello World");
final String response = ecx.readOutbound(); // Read using non-spied channel
verify(ec, times(2)).isOpen();
Assert.assertEquals(1, handler.reads.get());
Assert.assertEquals("dlroW olleH", response);
}
}
Thanks for any guidance here.
I am writing a test for already built java class function. I am writing tests using Testng and Mockito and have a Data Provider.
This is my Test
#Test(dataProvider = "myProvider", dataProviderClass = StaticDataProvider.class,
expectedExceptions = SomeException.class)
public void myControllerTest(String argument) throws Exception {
// Mocked object bussiness\
Boolean resultantObject = business.getList(argument);
Assert.assertTrue(resultantObject);
}
This is my Controller which I want to test
public Boolean controller(String argument) {
if(argument != null) {
throw new someException();
} else {
System.out.println("Sucess");
return true;
}
}
This is my Data Providor
#DataProvider(name = "myProvider")
public static Object[][] getDirectoryList() throws Exception {
Object[][] result = null;
// case1 throws SomeException
String testData1 = null;
// case2 don't throw exception
String testData2 = "String";
result = new Object[][] { { testData1 }, { testData2 } };
return result;
}
The problem here I am facing is, I don't want to create another test just to test both buggy and non buggy code and complete my test coverage using a single test case. But when I put Expected Exception on top, it fails on correct code, and when I dont, it fails on buggy code.
NOTE: This is example code and may not work, this is just to take an idea of scenario I am working on and what I am expecting.
Even if you ignore the "one test, one assertion" purist perspective, I think most people agree you should split tests that involve error conditions from tests that prove normal behaviour.
If you want to test multiple error conditions within one test (or if you're really keen on continuing with your plan), you can use this pattern:
try {
// something that should cause an exception
fail("Exception expected");
} catch (ExactlyTheRightException e) {
// ignored
}
I have written a few JUnit tests with #Test annotation. If my test method throws a checked exception and if I want to assert the message along with the exception, is there a way to do so with JUnit #Test annotation? AFAIK, JUnit 4.7 doesn't provide this feature but does any future versions provide it? I know in .NET you can assert the message and the exception class. Looking for similar feature in the Java world.
This is what I want:
#Test (expected = RuntimeException.class, message = "Employee ID is null")
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() {}
You could use the #Rule annotation with ExpectedException, like this:
#Rule
public ExpectedException expectedEx = ExpectedException.none();
#Test
public void shouldThrowRuntimeExceptionWhenEmployeeIDisNull() throws Exception {
expectedEx.expect(RuntimeException.class);
expectedEx.expectMessage("Employee ID is null");
// do something that should throw the exception...
System.out.println("=======Starting Exception process=======");
throw new NullPointerException("Employee ID is null");
}
Note that the example in the ExpectedException docs is (currently) wrong - there's no public constructor, so you have to use ExpectedException.none().
In JUnit 4.13 you can do:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
...
#Test
void exceptionTesting() {
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> { throw new IllegalArgumentException("a message"); }
);
assertEquals("a message", exception.getMessage());
}
This also works in JUnit 5 but with different imports:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
...
I like the #Rule answer. However, if for some reason you don't want to use rules. There is a third option.
#Test (expected = RuntimeException.class)
public void myTestMethod()
{
try
{
//Run exception throwing operation here
}
catch(RuntimeException re)
{
String message = "Employee ID is null";
assertEquals(message, re.getMessage());
throw re;
}
fail("Employee Id Null exception did not throw!");
}
Do you have to use #Test(expected=SomeException.class)? When we have to assert the actual message of the exception, this is what we do.
#Test
public void myTestMethod()
{
try
{
final Integer employeeId = null;
new Employee(employeeId);
fail("Should have thrown SomeException but did not!");
}
catch( final SomeException e )
{
final String msg = "Employee ID is null";
assertEquals(msg, e.getMessage());
}
}
Actually, the best usage is with try/catch. Why? Because you can control the place where you expect the exception.
Consider this example:
#Test (expected = RuntimeException.class)
public void someTest() {
// test preparation
// actual test
}
What if one day the code is modified and test preparation will throw a RuntimeException? In that case actual test is not even tested and even if it doesn't throw any exception the test will pass.
That is why it is much better to use try/catch than to rely on the annotation.
I never liked the way of asserting exceptions with Junit. If I use the "expected" in the annotation, seems from my point of view we're violating the "given, when, then" pattern because the "then" is placed at the top of the test definition.
Also, if we use "#Rule", we have to deal with so much boilerplate code. So, if you can install new libraries for your tests, I'd suggest to have a look to the AssertJ (that library now comes with SpringBoot)
Then a test which is not violating the "given/when/then" principles, and it is done using AssertJ to verify:
1 - The exception is what we're expecting.
2 - It has also an expected message
Will look like this:
#Test
void should_throwIllegalUse_when_idNotGiven() {
//when
final Throwable raisedException = catchThrowable(() -> getUserDAO.byId(null));
//then
assertThat(raisedException).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("Id to fetch is mandatory");
}
Raystorm had a good answer. I'm not a big fan of Rules either. I do something similar, except that I create the following utility class to help readability and usability, which is one of the big plus'es of annotations in the first place.
Add this utility class:
import org.junit.Assert;
public abstract class ExpectedRuntimeExceptionAsserter {
private String expectedExceptionMessage;
public ExpectedRuntimeExceptionAsserter(String expectedExceptionMessage) {
this.expectedExceptionMessage = expectedExceptionMessage;
}
public final void run(){
try{
expectException();
Assert.fail(String.format("Expected a RuntimeException '%s'", expectedExceptionMessage));
} catch (RuntimeException e){
Assert.assertEquals("RuntimeException caught, but unexpected message", expectedExceptionMessage, e.getMessage());
}
}
protected abstract void expectException();
}
Then for my unit test, all I need is this code:
#Test
public void verifyAnonymousUserCantAccessPrivilegedResourceTest(){
new ExpectedRuntimeExceptionAsserter("anonymous user can't access privileged resource"){
#Override
protected void expectException() {
throw new RuntimeException("anonymous user can't access privileged resource");
}
}.run(); //passes test; expected exception is caught, and this #Test returns normally as "Passed"
}
If using #Rule, the exception set is applied to all the test methods in the Test class.
I would prefer AssertJ for this.
assertThatExceptionOfType(ExpectedException.class)
.isThrownBy(() -> {
// method call
}).withMessage("My message");
I like user64141's answer but found that it could be more generalized. Here's my take:
public abstract class ExpectedThrowableAsserter implements Runnable {
private final Class<? extends Throwable> throwableClass;
private final String expectedExceptionMessage;
protected ExpectedThrowableAsserter(Class<? extends Throwable> throwableClass, String expectedExceptionMessage) {
this.throwableClass = throwableClass;
this.expectedExceptionMessage = expectedExceptionMessage;
}
public final void run() {
try {
expectException();
} catch (Throwable e) {
assertTrue(String.format("Caught unexpected %s", e.getClass().getSimpleName()), throwableClass.isInstance(e));
assertEquals(String.format("%s caught, but unexpected message", throwableClass.getSimpleName()), expectedExceptionMessage, e.getMessage());
return;
}
fail(String.format("Expected %s, but no exception was thrown.", throwableClass.getSimpleName()));
}
protected abstract void expectException();
}
Note that leaving the "fail" statement within the try block causes the related assertion exception to be caught; using return within the catch statement prevents this.
Import the catch-exception library, and use that. It's much cleaner than the ExpectedException rule or a try-catch.
Example form their docs:
import static com.googlecode.catchexception.CatchException.*;
import static com.googlecode.catchexception.apis.CatchExceptionHamcrestMatchers.*;
// given: an empty list
List myList = new ArrayList();
// when: we try to get the first element of the list
catchException(myList).get(1);
// then: we expect an IndexOutOfBoundsException with message "Index: 1, Size: 0"
assertThat(caughtException(),
allOf(
instanceOf(IndexOutOfBoundsException.class),
hasMessage("Index: 1, Size: 0"),
hasNoCause()
)
);
#Test (expectedExceptions = ValidationException.class, expectedExceptionsMessageRegExp = "This is not allowed")
public void testInvalidValidation() throws Exception{
//test code
}