I'm trying to create a when sentence, but I can't do it well because I don't know how to mock correctly whatever.
I have this code:
public class OperationMovement {
#Value("${operation.check}")
private Boolean needToCheck;
private void checkOperation() {
// Code
if (BooleanUtils.isTrue(needToCheck)) {
// More code
}
}
}
I need to create a test with Mockito, but I don't know how to mock this if else.
I have tried to mock the BooleanUtils this way:
#Mock
BeanUtils beanUtils;
// Code and more testing code
when(booleanUtils.isTrue(anyBoolean())).thenReturn(true);
But this returs an error.
I have tried the following too, but I have the same error:
when(BooleanUtils.isTrue(anyBoolean())).thenReturn(true);
I need to mock that propertie or the BooleanUtils class, but I don't know how.
Quick example usage:
private OperationMovement classUnderTest;
...
#Test
void testOperationIsTrue() {
// For this test case, you are setting it to true
ReflectionTestUtils.setField(classUnderTest,"needToCheck",true);
}
Related
I have a code that I cannot correctly cover with tests.
I am using the Mockito library.
And I had difficulty at the moment of starting the test.
Below is the test code:
#Test
public void testLoadCar() {
when(remoteService.loadData()).thenReturn(new DataResult<DataCar>("", "", new DataCar()));
when(dataResult.hasError()).thenReturn(true);
when(dataResult.response.hasHeaders()).thenReturn(true);
requestNetwork = new RequestNetwork(remoteService);
Response<DataCar> response = requestNetwork.load(request);
}
These are objects in the test class: remoteService, dataResult, request.
I am concerned about the moment where I am trying to implement the when method:
when(dataResult.response.hasHeaders()).thenReturn(true);
I would like to know if such a recording will work.
If it doesn't work, then how can we handle this moment:
protected Response createResponse(DataResult<T> dataResult) {
if (dataResult.hasError() || !dataResult.response.hasHeaders()) {
return dataResult.getErrorMessage());
} else {
return Response.data(dataResult.value);
}
}
This is a method on the system under test (SUT) that has a createResponse() method. This method contains a call to the mock method of the DataResult object.
To implement dataResult.hasError () I got it:
when (dataResult.hasError ()). thenReturn (true);
Then with! DataResult.response.hasHeaders () I have a problem. Since I don't understand how to substitute the value I need.
Not all objects that your object under test interacts with need to be mocks.
Remember that you can use POJOs as well.
DataResult looks like a perfect candidate for a POJO.
You gain nothing by using a mock objet if you can create a POJO with desired state and behaviour.
Looking at the posted code, it looks like it is easy to create:
new DataResult<DataCar>("", "", new DataCar())
On top of that:
Your code looks suspicious to me.
when stubbing remoteService.loadData() you create a new instance of DataResult
subsequently, you stub some calls on dataResult, which is not an object returned from remoteService.loadData()
And to answer original post:
You can set fields on mocks (directly if access modifiers allow it, or via reflection otherwise). Note that this is highly not-idiomatic and surprising use of mocks.
class A {
B b;
}
class B {
boolean hasHeaders() {
return true;
}
}
#ExtendWith(MockitoExtension.class)
public class AAATest {
#Mock
A aMock;
#Mock
B bMock;
#BeforeEach
void setupMocks() {
aMock.b = bMock;
}
#Test
void testFieldInMockIsInitialized() {
Assertions.assertEquals(bMock, aMock.b);
}
}
I'm trying to write a unit test for a function that has a condition for wifi state. When the wifi state is disconnected, the function returns with false, but I want to simulate a scenario when the wifi state is connected. How do I go about it? Should I make a setter for the state variable? Isn't that a bad approach?
The function I want to test:
public boolean performSomething() {
if (WIFI_STATE != "connected") {
return false;
}else{
....
}
}
I want to test the else part of the function above, but as you may have guessed, the function executes the if condition, and returns false because WIFI_STATE is "disconnected"
Without seeing any of your code, make sure your class uses a WifiState constructor parameter or injection (or something similar). In your test you can then provide a mock for this object and set the state accordingly to your testing needs.
Two approaches that I can think of:
1: Define a sensor's state capturing class say WifiStatus, which your production code initializes automatically through a static initializer.
For testing, you can load a dummy WifiStatus class though a test initializer or change the value of WifiStatus through instrumentation.
2: Use WifiStatus as a interface and then mock it for dependency injection. This approach is more common.
public interface WifiStatus{
boolean isConnected();//
}
public class Performer{
WifiStatus wifiStatusProvider;
public Performer(WifiStatus stateProvider){
this.wifiStatusProvider = stateProvider;
}
public boolean performSomething() {
//if (WIFI_STATE != "connected") {
if (wifiStatusProvider.isConnected() != true) {
return false;
}else{
....
}
}
}
For test class, you use as follows:
public class PerformerTest{
#Test
public void verifyPerformSomething(){
WifiStatus dummyWifiStatus = mock(WifiStatus.class);
doReturn(true).when(dummyWifiStatus).isConnected();
new Performer(dummyWifiStatus).performSomething();
}
}
Assuming you are talking about "Local Unit Tests" and not "Instrumented Unit Tests", you can use Robolectric: http://robolectric.org
http://robolectric.org/javadoc/3.0/org/robolectric/shadows/ShadowWifiManager.html
https://github.com/robolectric/robolectric/blob/master/robolectric/src/test/java/org/robolectric/shadows/ShadowWifiManagerTest.java
Local Unit Tests:
https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html
Instrumented Unit Tests:
https://developer.android.com/training/testing/unit-testing/instrumented-unit-tests.html
Well, for testing, you must be sure for your input how your output looks like because you need to compare them. Make the boolean value of wifi state is injected from outside, so you can mock it how you like. For example:
public boolean method(boolean wifiState){
return !wifiState;
}
So now you can be sure that if your parameter is false you will got true and vice versa so you can mock that param and make your tests.
Chiming in with a code-based answer based on john16384's answer. You mention that the state is set with other functions within the same class, assuming those methods are public I propose something like this (assuming WifiChecker is your class):
private WifiChecker wifiChecker;
#Before public void setUp() {
wifiChecker = new WifiChecker();
}
#Test public void testWifiConnected() {
wifiChecker.setConnected()
assertTrue(wifiChecker.performSomething());
}
#Test public void testWifiDisconnected() {
wifiChecker.setDisconnected()
assertFalse(wifiChecker.performSomething());
}
I am writing Junit test for the below code using Mockito but I am getting a null pointer exception is there a mistake in the way I'm mocking it?
public boolean isApplyChecked()
{
return _rranalysis.getApplytoAllState();
}
and my test case is
#Test
public void testIsApplyChecked() {
JCheckBox Rra_Apply_Field = Mockito.mock(JCheckBox.class);
Mockito.when(Rra_Apply_Field.isSelected()).thenReturn(true);
RepeatRejectAnalysis rs = Mockito.mock(RepeatRejectAnalysis.class);
Mockito.when(rs.getApplytoAllState()).thenReturn(true);
boolean val = repeatRejectAnalysis_Listener.isApplyChecked();
Assert.assertEquals(true, val);
}
You have to inject the RepeatRejectAnalysis class dependency into your repeatRejectAnalysis_Listener. For example:
Use setter
RepeatRejectAnalysis rs =Mockito.mock(RepeatRejectAnalysis.class);
Mockito.when(rs.getApplytoAllState()).thenReturn(true);
repeatRejectAnalysis_Listener.setAnalysis(rs);
boolean val=repeatRejectAnalysis_Listener.isApplyChecked();
Use #InjectMocks
public class ListenerTest{
#InjectMocks
private Listener repeatRejectAnalysis_Listener = new Listener();
#Mock
private RepeatRejectAnalysis rs;
#Before
public void init(){
MockitoAnnotation.initMocks(this);
}
// reuse the exact same method as you have now.
#Test
public void testIsApplyChecked() {
JCheckBox Rra_Apply_Field=Mockito.mock(JCheckBox.class);
Mockito.when(Rra_Apply_Field.isSelected()).thenReturn(true);
RepeatRejectAnalysis rs =Mockito.mock(RepeatRejectAnalysis.class);
Mockito.when(rs.getApplytoAllState()).thenReturn(true);
boolean val=repeatRejectAnalysis_Listener.isApplyChecked();
Assert.assertEquals(true, val);
}
}
The other answer is correct about that one missing piece of mocking that you need. But then: none of the mocking that you have in your current test case seems to be required.
The idea of tests is to use a (minimal!) setup containing exactly those steps that are really mandatory to enable a test.
There is no point in mocking a JCheckBox ... when the method you intend to test doesnt make use of that check box in any way!
I am new to writing tests in java, and seem to be unable to test if a method of a class is called.
I am sending metrics to datadog, and want to test in the code if a function of another class was called.
It says I need to mock first, but I couldn't get it to work.
MetricRecorder.java
import com.timgroup.statsd.StatsDClient;
import com.timgroup.statsd.NonBlockingStatsDClient;
import com.google.common.base.Preconditions;
public class MetricRecorder {
private final String namespace;
private final static StatsDClient metrics = new NonBlockingStatsDClient(
"my.prefix",
"localhost",
8125,
new String[] {"tag:value"}
);
public MetricRecorder(String namespace) {
Preconditions.checkNotNull(namespace);
this.namespace = namespace;
}
public void inc(String metricName) {
this.inc(metricName, 1);
}
public void inc(final String metricName, final long value) {
Preconditions.checkNotNull(metricName);
try {
metrics.recordHistogramValue(MetricRecorder.name(namespace, metricName), value);
} catch (Exception e) {
logger.warn("Unable to record metric {} due to :", metricName, e);
}
}
...
}
MetricRecorderTest.java
public class MetricsRecorderTest {
#Test
public void metricsRecorderTest() {
MetricRecorder recorder = new MetricRecorder("dev");
recorder.inc("foo", 1);
verify(recorder.metrics, times(1)).recordHistogramValue(eq("dev.foo"), 1);
}
}
When I run the test I get this => org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type NonBlockingStatsDClient and is not a mock!
Any idea of how I should be testing if recordHistogramValue was called, and if so with what arguments?
Since it looks like StatsDClient is an interface of some kind, it would make your testing effort easier to simply inject this dependency into your object. Even if you're not using an IoC container like Spring or Guice, you can still somewhat control this simply by passing an instance of it in through the constructor.
public MetricRecorder(String namespace, StatsDClient client) {
Preconditions.checkNotNull(namespace);
Preconditions.checkNotNull(client);
this.namespace = namespace;
this.client = client;
}
This will make your testing simpler since all you realistically need to do is mock the object passed in during test.
Right now, the reason it's failing is because you're newing up the instance, and Mockito (in this current configuration) isn't equipped to mock the newed instance. In all honesty, this set up will make testing simpler to conduct, and you should only need your client configured in one area.
#RunWith(MockitoJUnitRunner.class)
public class MetricsRecorderTest {
#Test
public void metricsRecorderTest() {
StatsDClient dClientMock = Mockito.mock(StatsDClient.class);
MetricRecorder recorder = new MetricRecorder("dev", dClientMock);
recorder.inc("foo", 1);
verify(recorder.metrics).recordHistogramValue(eq("dev.foo"), 1);
}
}
You are getting things wrong here. You don't use a mocking framework to test your "class under test".
You use the mocking framework to create mocked objects; which you then pass to your "class under test" within a test case. Then your "code under test" calls methods on the mocked object; and by controlling returned values (or by verifying what happens to your mock); that is how you write your testcases.
So, your testcase for a MetricRecorder doesn't mock a MetricRecorder; it should mock the StatsDClient class; and as Makoto suggests; use dependency injection to put an object of that class into MetricRecorder.
Besides: basically writing "test-able" code is something that needs to be practiced. I wholeheartedly recommend you to watch these videos if you are serious about getting in this business. All of them; really (worth each second!).
I need to write unit tests against a pre-existing code base using TestNG, Mockito and now PowerMockito, to test private and static methods more easily. I am currently trying to write a test against a private void method in a class that we are testing, but am unable to figure it out. In the normal PowerMock API there are methods called replayAll(), verifyAll(), and expectLastCalled(), which are suitable for most purposes. I just can't find good docs that explain how to do it the PowerMockito way. Any explanations or insights on this would be much appreciated.
Method to test:
private void pVMethod(Type param) throws Exception {
param.setA(StaticClass.methodA().toString());
param.setB(StaticClass.methodB().toString());
// getMemo(String label) is in a public class in same package
param.setC(getMemo("memo.provider"));
param.setD(getMemo("memo.item"));
try {
param.setTimestamp(DataTypeFactory.newInstance().newXMLGregorianCalendar(newjava.util.GregorianCalendar()));
} catch (SomeException e) {
...
throw new Exception();
}
}
test attempt:
#Test(expectedExceptions = Exception.class)
public void pVMethod() throws Exception {
TestClass testMock = mock(TestClass.class);
Exception exception = mock(Exception.class);
// StaticClass staticClassMock = mock(StaticClass.class); ??
mockStatic(StaticClass.class);
// when(..) and thenReturn(..) are static imports from PowerMockito library
when(StaticClass.methodA()).thenReturn("stubStringA");
when(StaticClass.methodB()).thenReturn("stubStringB");
doThrow(exception).when(param).setTimestamp(Mockito.any(XMLGregorianCalendar.class));
// Docs say method name can be inferred via reflection
Whitebox.invokeMethod(tested, event);
// this is where things are hairy. testedSpy is defined at the top level
verifyPrivate(testedSpy).pVMethod(testMock);
}
Ok, here is the answer:
In PowerMockito, if you want to verify the behavior of a private void method you use the verifyPrivate() method, but you have to do it like this:
verifyPrivate(tested).invoke("privateMethodName", argument);
Notice the use of the invoke method, missing from the last line of the OP.
NOTE: You do not have to use a doNothing().when(mock.privateMethod()) statement, because void methods in mock objects don't do anything by default.
example taken from here