I am writing an application to draw sketches in javaFX.
Currently you can draw and erase with different colors. Among the commands I have written is "erase all". But I don't know how to test it. This command allows you to erase all the lines drawn on the canvas. There can be many approaches to achieve this. For example, you could replace the entire canvas with a new one to "reset" it, or you could use several functions to act on the color and return all pixels to the original color of the canvas, for example. I chose the second approach. So, the command I bind to the button is as follows:
import javafx.scene.canvas.Canvas;
public class EraseAllCommand implements Command {
private final Canvas canvas;
public EraseAllCommand(Canvas canvas) {
this.canvas = canvas;
}
@Override
public void execute() {
this.canvas
.getGraphicsContext2D()
.clearRect(0, 0, this.canvas.getWidth(), this.canvas.getHeight());
}
}
Now, what is the outcome to consider for testing this behavior effectively?
- Class
javafx.scene.canvas.GraphicsContext
is a final class and does not extends or implements any class or interface, so I didn't know how to fake it. I considered to use mocks of Mockito, then. - I found this question I considered useful but in my case I get a "blank" canvas without any css property modification (see my implementation above).
- I could use robots but I don't think is a good solution. Should I check the color of every pixel? Is there a performant way to achieve this?
I finally created a mock but is strongly based on implementation and that's bad because there are several approaches to solve this problem. Could I mock in some cleverer ways? I created a stub Canvas
of mine just to wrap a mock GraphicsContext
into it. What should I consider as a testable outcome?
Here is my bad test:
public class EraseAllTest {
@Test
public void should_erase_all() {
GraphicsContext mockGraphicsContext = Mockito.mock( GraphicsContext.class );
final var eraseAllCommand = new EraseAllCommand( new StubCanvas( mockGraphicsContext ));
eraseAllCommand.execute();
Mockito.verify( mockGraphicsContext ).clearRect(0, 0, 0, 0);
}
}
I am currently using javaFX 18, junit5 5.9.0, Mockito 4.0.0.
A perfect solution, to me, would be an approach let me change the implementation without change the test. Any suggestions? Thanks a lot.