Given a class annotated with #Log; is it possible to mock the injected logger with Mockito for unit testing? Is this correct "Groovy-way" of doing things?
We've been having some issues while using Mockito with Groovy, as it is described here. Perhaps, you might want to use another mocking framework with Groovy support, such as GMock.
For more info you can check also this link.
The way I've achieved this is to define another Logger variable within the class to be tested, non-final and with a more permissive scope. The constructor then defaults to taking the injected logger and assigning it the more permissive object. In the tests, the logger instance can be set to a mockito mocked object which is then assigned to the more permissive object.
Not as perfect as allowing for the mocking of injected objects; but functional.
Related
I want to mock a constructor and return a mock object when the constructor is called. This can be achieved using powermockito's whenNew method like this.
PowerMockito.whenNew(ClassName.class).withAnyArguments().thenReturn(mockObject);
Since Junit5 doesn't have powermockito support yet, I need to know if this can be achieved using Mockito.
Mockito 3.5 has added alot of PowerMock's functionality into core Mockito. It now has a method, mockConstruction(), that you can use to mock constructors. Reference: https://rieckpil.de/mock-java-constructors-and-their-object-creation-with-mockito/
I have a db service save() method which allows method chaining:
#Service
public class Service {
...
public Service save(...) {
...
return this;
}
and this works just great as:
service.save(this).save(that).save(other);
When I come to mock it with Mockito though it breaks unless I use
Service serviceMock = mock(Service.class, RETURNS_DEEP_STUBS);
IIUC though, the use of RETURNS_DEEP_STUBS is considered bad. Is there a better way to mock a class with method call chaining?
Your pattern for save is very similar to a Builder pattern, which makes the question similar to "How to mock a builder with mockito" elsewhere on SO.
Per David Wallace's answer there, you can write an Answer that detects whether the mock is an instance of the return type of the method, and return the mock in only that case. This functionality was also built into the Mockito library as RETURNS_SELF in Mockito 2.0. As with any Answer, you can use this on any specific method call with thenAnswer or as the second parameter of mock to make it the default answer, but bear in mind the Mockito documentation warning that methods with generous return types (e.g. Object) will return the mock whether or not that was intended.
I'm wondering,
If in #Before method I'm initializing a mock objects, shouldn't I nullify references to it in #After ? Or would that be redundant? And why?
Not necessary, JUnit creates a new instance of the test per test method.
However if it's static fields it's another story, and proper lifecycle should be implemented, but I strongly advise you to not use static fields in a JUnit test ! Instead think about implementing your own JUnit Runner.
And for TestNG, it's a different story, as TestNG creates a single instance of the test, so you have to be careful there on the lifecycle of the mocks.
"Nullifying" reference doesn't change anything here.
#Before annotated method is ran before each test method. If you are initializing mocks in such method they will be reinitialized before each test. There is a different annotation - #BeforeClass, this annotation causes a method to be executed only once before execution of any test method in that test class. In this case however "nullifying" a reference will not help you because you still need to create a new mock object and assign its reference to your field.
If it doesn't, does it exist on EasyMock?
Thanks.
PowerMock is intended as an extension of both EasyMock and Mockito. From the horse's mouth: "PowerMock is a framework that extend other mock libraries such as EasyMock with more powerful capabilities."
In any case, there is no EasyMock equivalent to expectNew and neither is there one in Mockito, either - that's exactly the hole that PowerMock is trying to fill. That being said, PowerMock is perfectly capable of doing this with Mockito. Here is the sample from the documentation:
How to mock construction of new objects
Use PowerMockito.whenNew, e.g.
whenNew(MyClass.class).withNoArguments().thenThrow(new
IOException("error message"));
Note that you must prepare the class
creating the new instance of MyClass for test, not the MyClass itself.
E.g. if the class doing new MyClass() is called X then you'd have to
do #PrepareForTest(X.class) in order for whenNew to work.
How to verify construction of new objects
Use PowerMockito.verifyNew,
e.g.
verifyNew(MyClass.class).withNoArguments();
In my attempt to mock an object in Groovy using the mock.interceptor package:
def mock = new MockFor(TheClass);
mock.demand.theMethod{ "return" }
mock.use {
def underTest = new TheClass()
println underTest.theMethod()
}
The problem I have is when creating TheClass() in the use{ block, it uses the actual constructor which, in this circumstance, I'd rather it not use. How can I create an instance of this class so I can test the method I do care about, theMethod, without needing to use the constructor?
Using EasyMock/CE, mocks can be made without using the constructor, but am curious how to achieve that in Groovy.
I recently saw a presentation by the author of GMock and it has some hooks to allow "constructor" mocking which I think is what you are after.
e.g.
def mockFile = mock(File, constructor('/a/path/file.txt'))
This library differs from that "built in" to groovy, however it looked very well written, with some thought put into the kinds of things you want to mock and more importantly the error messages you would get when tests should fail.
I think this is what you are after. I would say use constructor mocking with care - it could be a smell that you should inject a Factory object, but for some things it looked to work well.
You can use the interceptConstruction flag when calling MockFor, see
MockFor.