how to throw IOException while reading a file using Mockito? - java

I have to throw an IOException using Mockito for a method, which is reading an input stream like given below. Is there any way to do it?
public void someMethod() {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
firstLine = in.readLine();
} catch(IOException ioException) {
// Do something
}
...
}
I tried mocking like
BufferedReader buffReader = Mockito.mock(BufferedReader.class);
Mockito.doThrow(new IOException()).when(buffReader).readLine();
but didn't work out :(

You're mocking a BufferedReader, but your method doesn't use your mock. It uses its own, new BufferedReader. You need to be able to inject your mock into the method.
It seems that inputStream is a field of the class containing this method. So you could mock the inputStream instead and make it throw an IOException when its read() method is called (by the InputStreamReader).

You can't mock BufferedReader here since it's being created inside the method.
Try mocking inputStream and throwing the exception from InputStream.read() instead.

The way that I would recommend is to have an extra class that looks after the creation of the BufferedReader. This class has just one method, with no actual logic in it, so it doesn't need any unit tests.
public class BufferedReaderFactory{
public BufferedReader makeBufferedReader(InputStream input) throws IOException{
return new BufferedReader(new InputStreamReader(input));
}
}
Now, add a private field of type BufferedReaderFactory to the class that you're testing, along with a means of injecting it - either a setter method or an alternate constructor. In the standard constructor for your class, instantiate a BufferedReaderFactory and set the field accordingly. In your someMethod(), call the makeBufferedReader() method on the field, instead of using new.
Your class is much more testable; because now, you can write a test that injects a mocked BufferedReaderFactory to the object that you're testing, before calling someMethod(). On that mock, you can stub the makeBufferedReader method to throw the exception that you want.
Please add a comment if you want me to go into more detail on any of the steps above. You might also like to read my post on mocking object creation on the Mockito wiki; which is closely related to this.
But the most important message is that making your classes testable is really important, and you will reap the benefits of doing so many times over.

Related

Creating an object from a saved one in its constructor

To be clear: I have an object which is continiously changing its values during the runtime and I want to save the created and modified object on a file.
I found how to that and I found also how to read back the object saving it into one another. But the question is: is it possible to call the class constructor of my object with the only parameter of the file in which the object I want to retrieve is stored?
NeuralNetwork(File fs){
ObjectInputStream ois;
changeFileSave(fs); //just sets the file as savefile for the future
try{
ois = new ObjectInputStream(new FileInputStream(_saveNet)); //_saveNet = fs
this = (NeuralNetwork) ois.readObject();
}
catch(Exception e){
//error message
}
}
It gives me an error on 'this ='
If it's possible how do I do something like this?
Thank you
The keyword this is a read-only reference, you can never write this = even in the constructor. Moreover, the constructor in java does not return anything.
You would have to take the object you've read and map its properties one by one (or using reflection) to the properties you have in the object you're instantiating.
However, I would submit that by passing a file to a constructor and doing the IO in it you are violating separation of concerns. By writing things this way, you have forever tied a neural network to a File, with a whole host of attendant issues, including (not limited to) the fact that you may be storing your values elsewhere at some point.
IMO you are better off using a factory pattern to build your object and making your NeuralNetwork object a plain object. Then the ambiguity disappears because your factory method can simply return (NeuralNetwork) ois.readObject();
this = (NeuralNetwork) ois.readObject();
Consider this as a hidden final argument that points to the instance that is executing the method. Its value cannot be changed. If you want to make a variable point to an instance, there's no problem with that, as long as you don't use this.
What you want to do is more appropriate for a factory or factory method than for a constructor. Use one of this patterns (or a static method if you want to keep it very simple) to create your instance from the file. Not sure if you need many instances of that class, but if you only need one, you should consider using a Singleton getInstance() method instead the previously mentioned.
You can't assign this, since it is readonly. this always points to the instance itself and is used throughout the life of the object to access its methods and attributes.
If you want to create an instance of your NeuralNetwork class by reading data from a file, you could use a factory method:
public class NeuralNetwork {
private NeuralNetwork() { // private constructor forces us to use the
} // factory method to create instances
public static NeuralNetwork loadFromFile(File fs) {
ObjectInputStream ois;
this.changeFileSave(fs); // just sets the file as savefile for the future
try {
ois = new ObjectInputStream(new FileInputStream(_saveNet));
return (NeuralNetwork) ois.readObject();
}
catch(IOException e){
throw UncheckedIOException(e);
}
}
// other methods and attributes
}
Then, wherever you use your NeuralNetwork class and need an instance, use:
NeuralNetwork network = NeuralNetwork.loadFromFile(someFs);
// use network instance and have fun with it here
Note 1: I've defined a private constructor to force everyone use the loadFromFile factory method to create an instance. This means that this class can only be created from within a static method of this class.
Note 2: I've also rethrown the exception with an unchecked exception. This is personal taste. I wouldn't just log the exception and go on. Instead, I would throw the exception so that the caller handles it properly, because it doesn't make any sense to go on if an instance of the class hasn't been created. If you don't want to rethrow the exception as an unchecked one, just don't catch the original IOException and add a throws IOException clause to your factory method. This would force the callers of loadFromFile to catch the IOException and handle it.

How to write a method header that throws exception

"Given that FileInputStream’s constructor throws FileNotFoundException, which is a subclass of
Exception, write the header for a public method named process that takes a String parameter
and returns nothing, and whose body instantiates a FileInputStream object and does not contain
a try-catch statement."
I know it's a too-simple question but I want to make sure I'm not messing up in a dumb way. Also, not sure whether to use FileNotFoundException or just Exception or IO, etc.
public process(String file) throws FileNotFoundException {
FileInputStream file = new FileInputStream("stuff.txt");
}
What you have for the throws clause is good. Throwing IOException would not be terrible, but it's better to be specific. Calling code can still treat it as an IOException.
Generally you shouldn't throw Exception except for special cases (Junit methods and similar situations where everything thrown will get caught by an exception handler), because it forces everything that calls it into the position of either handling Exception (where it may not be the appropriate place to do it, it is better to let most exceptions bubble up to one place where they can get handled uniformly) or also throwing Exception, which then puts other calling methods in the same position.
Your method declaration is not valid because there's no return type. Methods that don't return anything are declared with a return type of void.
Using the same name for a method parameter as for a local variable will not work, you should make those different. The constructor call should take the method parameter as an argument (instead of hard-coding a string literal). (+1 to geceo's answer for pointing that one out, I had missed that one.)
As a suggestion, your code would be clearer if it used names that reflected the contents of the variables. Calling a FileInputStream file is not clear, it would be better to call it inputStream. Calling a String file is not clear, it would be better to call it filename.
What you have is fine (except you're missing the void return type).
Always throw (and catch) the narrowest specification of Exception you can (in this case FileNotFoundException).
As spotted by Nathan, you forgot to declare that process returns nothing, that is, you forgot the void keyword.
There's another problem with your parameter String file ("duplicate local variable file"). You should rename it String filename and pass it to the constructor of FileInputStream:
public void process(String filename) throws FileNotFoundException {
FileInputStream file = new FileInputStream(filename);
}
About the general topic, you always have to make a choice when you call a method that throws exception(s):
You can use a try/catch block and deal with the error in your calling method (log them, for example);
or
You can propagate the exception using the throws keyword in your method declaration.
So what you're doing here is the second possibility.
Also add void as the return type. Rest is fine.
public void process(String file) throws FileNotFoundException {
FileInputStream file = new FileInputStream("stuff.txt");
}
You can do few things to make your method better by buying insurance against accidental misuse:
public void process(final String file) throws FileNotFoundException {
final FileInputStream inputStream = new FileInputStream("stuff.txt");
//invoke operations on inputStream object
//After 100 lines of code
inputStream = new FileInputStream("foo.txt"); // compile error
}
Observe the final keyword next to parameter passed to method and FileInputStream object reference.

Use Mockito to mock java.nio.file.Files static methods

I'm trying to understand how you can mock static methods, specifically from the static Files.class.
Basically, whenever this line executes:
Files.newInputStream(this.getPathObj(), StandardOpenOption.READ);
I want it to just return an object that is an instance of an InputStream.
The is my class with the static method I'm trying to mock.
public class JavaFileInput{
private Path path;
public JavaFileInput(Path path){
this.path = path;
}
public InputStream getInputStream() throws IOException {
return Files.newInputStream(this.getPathObj(), StandardOpenOption.READ);
}
public Path getPathObj() {
return this.path;
}
}
This is some "psuedo-ish" unit test code that obviously doesn't work, but I hope it portrays the idea of what I'm trying to accomplish.
#Mock(name="path")
private Path mockedPath = Mockito.mock(Path.class);
#InjectMocks
private JavaFileInput javaFile_MockedPath;
#Before
public void testSetup(){
javaFile_MockedPath = new JavaFileInput(mockedPath);
MockitoAnnotations.initMocks(this);
}
#Test
public void getNewInputStreamTest(){
//Setup
Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(new InputStream());
//Test
InputStream outputValue = javaFile_MockedPath.getInputStream();
//Validate
assertTrue(outputValue instanceof InputStream);
}
Does this make any sense? Has anyone ever had to do something similar? Any help would be greatly appreciated.
Thanks for your time!
I'm not clear what value your JavaFileInput provides. However, to test static methods you can look at PowerMock.
I came across the same problem: I have (own) code which modifies symlinks using nio.Files.
For testing my code without having to prepare and access the file system, I had to write an own mockable wrapper class around these functions.
Not so nice though that the nio JSR didn't consider this use case by defining an official interface and providing a non-static (=injectable) way for accessing Files. Mockito was known long before this..
Instead of using Mockito or PowerMock, you may also use a NIO2 implementation that work in memory:
memoryfilesystem
jimfs
While this won't solve all case (or let say it, it won't answer your attempt at mocking a static method) or allow you to create flawed InputStream (for example, one that would return an error when reading N bytes), this may suit your use case.
Also you ask if your case make any sense:
//Setup
Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(new InputStream());
//Test
InputStream outputValue = javaFile_MockedPath.getInputStream();
//Validate
assertTrue(outputValue instanceof InputStream);
You are testing that outputValue is indeed an instance of InputStream, which the compiler already does for you: outputValue is already an instance of InputStream, therefore asserting it is an instance of InputStream will never fails and your test is not checking what you want to check.
You'd best to test that outputValue is exactly the same instance as one returned, using a mock rather than new InputStream for example:
InputStream is = mock(InputStream.class);
Mockito.when(Files.newInputStream(mockedPathObj, StandardOpenOption.Read)).thenReturn(is);
InputStream outputValue = javaFile_MockedPath.getInputStream();
assertTrue(outputValue == is);
With standard Mockito, you can't mock static methods -- and I would question your reasons for doing so.
What do you seek to test by mocking the newInputStream method? You are merely creating a tautology -- that your method returns what you told it to return. And instanceof InputStream is a tautology as well.
It would make more sense to mock JavaFileInput to test another class that depends on it (perhaps by using a ByteArrayInputStream with sample data).

How to mock concrete class void method

I'm trying to mock Lucenes IndexReader.close() to do nothing.
I thought this should work...
IndexReader reader = Mockito.mock(IndexReader.class);
Mockito.stubVoid(reader).toReturn().on().close(); // old approach
Mockito.doNothing().when(reader).close(); // new approach
but both result in the unit test calling the actual, real close method and ultimately causing a null pointer exception.
What have I missed?
As the javadoc indicates, close() is a final method. And Mockito can't mock final methods.

How to mock an exception when creating an instance of a new class using Mockito

Within a method, I have an exception being caught which I want to mock.
I know how to mock an object to throw an exception using mock.doSomething(), but I need to throw a remote exception when a class makes a new instance of itself.
transient Bicycle bike = null;
public Bicycle getBicycle() {
if (bike == null) {
try {
bike = new Bicycle(this);
} catch (RemoteException ex) {
System.out.println("No bikes found");
}
}
return bike;
}
I want to be able to mock everything in the try block, but I don't understand how you mock the creation of a new class, the following line to be specific:
bike = new Bicycle(this);
I have tried many different Mockito tests, such as:
Bicycle b = mock(Bicycle.class);
Mockito.doThrow(new RemoteException()).when(b = new Bicycle());
Although I understand this will and is not working, I want to do something similar.
I have read the Mockito docs and haven't found anything useful:
http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html
You don't generally mock constructors. You can do with tools like PowerMock, but I'd generally suggest you don't.
Currently, your code isn't actually testable, if you want to control what happens when a new Bicycle is constructed. Is constructing a Bicycle actually a complex operation? Perhaps you want a BicycleFactory, which can be passed into your class as a dependency, for example - then you could mock BicycleFactory.createBicycle or whatever you call it.
Constructors are like static methods - when you use them, you're tightly bound to the specific code you're calling; there's no clean way to inject other behaviour without approaches like PowerMock's.
You can use a Mockito extension, PowerMock, in cases like this. It allows constructors to be mocked (see https://code.google.com/p/powermock/wiki/MockConstructor).
In this case, you would write something like the following test:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassUnderTest.class, Bicycle.class})
public class ConstructorMockingTest
{
#Test
public void getBicycle()
{
ClassUnderTest tested = new ClassUnderTest();
whenNew(Bicycle.class).withArguments(tested).thenThrow(new RemoteException());
Bicycle bicycle = tested.getBicycle();
assertNull(bicycle);
}
}
More examples can be found at: https://code.google.com/p/powermock/source/browse/trunk/modules/module-test/mockito/junit4/src/test/java/samples/powermockito/junit4/whennew/WhenNewTest.java
Your getBicycle() now does at least two things. It retrieves ("gets") a Bicycle, and it creates a Bicycle. Ideally a method or class should do only one thing, and do it well.
Put the creation of the object in a separate method createBicycle() or separate BicycleFactory and mock that.

Categories