I have a class that I am trying to unit test. This class extends another class that I am not interested in unit testing at this time.
The following code is an over simplification of the code I am trying to test.
package com.example.somePackage;
public class ApiBase {
protected <T extends SomeClass> t getApi(Class<T> apiClass) {/* some logic*/}
}
package com.example.anotherPackage;
public MagicApiImpl extends ApiBase {
private final MagicApiHandler apiHandler = new MagicApiHandler();
public String doSomeStuff(String someString) {
final BookApi bookApi = getApi(BookApi.class);
// some logic
return apiHandler.someMethod(bookApi, someString);
}
}
I would like to test doSomeStuff() on MagicApiImpl The part I would like to mock is what comes back in getApi().
At first go I tried simply creating an Instance of MagicApiImpl and setting all the behind the scenes things that happen but that started to become over complex for the scenario I want to test and the number of times I need to test it in other classes. I will handle the testing of the logic in getApi() in a test of its own.
It would be helpful to use EasyMock to test this as it is what a majority of the tests for this project are written in but I would not be overly apposed to using mockito.
Edit
Okay I was reading about the Mockito.spy() That would have been wonderful but sadly getApi is protected and in another package. Worst case I could fall back on placing all the tests in that package but that makes it difficult track code.
Using Easymock partial mocks your test should look like this:
#Test
public void test() {
MagicApiImpl impl = EasyMock.createMockBuilder(MagicApiImpl.class)
.addMockedMethod("getApi")
.createMock();
EasyMock.expect(impl.getApi(BookApi.class)).andReturn(/**Wharever you need*/);
EasyMock.replay(impl);
String input = "INPUT";
String output = impl.doSomeStuff(input);
System.out.println("The OUTPUT is: " + output);
EasyMock.verify(impl);
//Run asserts here
}
Reference: http://easymock.org/user-guide.html#mocking-partial
Related
I have written 1 assert test case for my Java program. I need to write one more test case for my program to pass Sonarqube test. I am not sure what other assert test case I can write to pass this sonarqube test.
Here is my code for Tools.java
#Component("Tools")
public class Tools implements Consumer<PMessage> {
private final OptimisticLockmark<Tble> mark;
private final giver giver;
public Tools(
final OptimisticLockmark<Tble> mark,
final giver giver) {
this.mark = mark;
this.giver = giver;
}
#Override
public void accept(PMessage PMessage) {
LOG.info("ignore "+PMessage.getKey());
}
}
Here is the test case I wrote for this class
public class DTest
{
#Before
public void setUp()
{
message = PMessage.builder()
.ingestedData("Test")
.key("1")
.build();
consumer =
new Tools(mark,
giver);
}
#Test
public void accept()
{
consumer.accept(message);
assertTrue("Pass", true);
}
}
I need some guidance to write one more assert test case to pass sonarqube.
In my opinion, your unit test is complete. The consumer class you are testing is designed to do nothing apart from generate an "info" log message to say it has done nothing.
Since "do nothing" cannot fail, and it is impractical to test that something has NOT "done nothing", you have tested all that you could test.
A pedant might argue that you need to test that the "info" log message is being logged. However, informational logging is not normally considered to be something that you need to test.
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 just now started using junit/unit tests facilities. And now I feel what goodness it is :) Is it possible to print field values if a junit test fails?
My method try implement INT(A(D — B)^C):
public static int countFieldEventPoints(PointsCountingTableRow row,float centimetres){
float temp = row.getA()*(float)Math.pow((centimetres - row.getB()),row.getC());
return roundUP(temp);
}
My test:
public void testCountlongJumpEventPoints(){
PointsCountingTableRow row = Tables.get2001table().getLongJump();
float cm = 736f;
assertEquals(900,PointCounterService.countFieldEventPoints(row,cm));
}
console print:
java.lang.AssertionError:
Expected :900
Actual :901
round up method (I feel there is the problem):
private static int roundUP(double floatNumber){
return (int) Math.round(floatNumber + .5);
}
row class:
public class PointsCountingTableRow {
private float A;
private float B;
private float C;
public PointsCountingTableRow(float a, float b, float c) {
A = a;
B = b;
C = c;
}
public float getA() {
return A;
}
public float getB() {
return B;
}
public float getC() {
return C;
}
}
Welcome to the wonderful world of Unit Testing :) For the sake of code covering, it's a good practice to code a set of test methods for each public method in your API: one for each interesting case, including successful and failing tests (thanks to Florian Schaetz).
What to do then, whith private methods (as roundUP) ? They also deserve a test battery, which you can easily design after a simple refactorizing of your API:
Create a new "helper" class with package (default) access, and a private constructor. This class will contain just public static methods.
Move roundUP from its actual container class to the helper class, and make it public.
Create a public tester class, in the same package (thus granting it access to the helper class), and fullfil it with the necessary testing methods.
Back to your case, you can code several testing methods to benchmark roundUP properly: I suggest ten methods: roundUP(0.0), roundUP(0.1), roundUP(0.2) ... roundUP(0.9).
As part of the Test Driven Development, every time a new error in your program is reported, you must then code a new tester method to reproduce such an error. Then, fix the bug until all the testers work OK (the new and the existing ones): In this way the test battery will grow and make sure that no updates nor fixes will accidentally break the existing behaviour.
Is it possible to print row fields values if test fall?
Of corse. You can program your testing methods to react in case of fail, in this way:
#Test
public void myTest()
{
// Prepare the input parameters:
PointsCountingTableRow row=...
float centimetres=...
// Perform the test:
int result=countFieldEventPoints(row, centimeters);
// Check the results:
String messageInCaseOfFail="row="+row.toString();
assertEquals(messageInCaseOfFail, expectedResult, result);
}
Or also through the fail methd:
#Test
public void myTest()
{
// Prepare the input parameters:
...
// Perform the test:
try
{
int result=countFieldEventPoints(row, centimeters);
// Check the results:
assert...
}
catch (SomeException e)
{
fail(messsageInCaseOfFail);
}
}
Is it possible to print field values if a test fails?
Of course it is. However, I wouldn't recommend doing that. Instead, if a unit test fails, and you can't see why it is happening by looking at the code, then I would recommend that you do the following:
run the failing test in your IDE's debugger,
set a breakpoint at the appropriate point, and
use the debugger UI to examine the state of the objects and variables directly.
I'd only implement diagnostic (e.g. display) code in a unit test suite in particularly complicated cases.
Adding diagnostic code to a unit test only increases the volume of code that needs to be read and maintained. Besides, it is only necessary for a test that fails ... and that is a scenario that you are aiming to eliminate.
Let's say I have the following classes in the respective source folders/packages...
[src/myApp]
|_Employee «concrete»
|_Manager «abstract»
|_ManagerImpl «concrete» (Class Under Test)
|_Recruiter «abstract»
|_RecruiterImpl «concrete» (Collaborator)
...
public class ManagerImpl implements Manager {
...
private Recruiter recR;
...
public void growTeam( Object criteria ){
//...check preconditions
Employee newB = recR.srcEmployee( criteria );
//...whatever else
}
...
}
...
[test/myApp]
|_RecruiterStandIn «concrete»
|_ManagerImplTest
...
public class RecruiterStandIn implements Recruiter {
Map<Object, Employee> reSrcPool = new HashMap<>();
public RecruiterStandIn( ){
// populate reSrcPool with dummy test data...
}
public Employee srcEmployee( Object criteria ){
return reSrcPool.get( criteria );
}
}
...
public class ManagerImplTest {
...
// Class Under Test
private ManagerImpl mgr;
// Collaborator
private Recruiter recR = new RecruiterStandIn( );
...
public void testGrowTeam( ) {
//...
mgr.setRecruiter( recR );
mgr.growTeam( criteria );
// assertions follow...
}
...
}
...
Here are my questions: Given that I have a RecruiterStandIn concrete implementation that already exists within the codebase for testing purposes (in the test scope)...
Would it be redundant to also use a mock in the above unit test?
What would be the value (if any) in additionally doing something like this in the above unit test?
...
...
#Mock
private Recruiter recR;
...
...
public void testGrowTeam( ) {
...
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
...
You can safely assume that RecruiterStandIn does everything the class under test will ever require of it for the purposes of the above unit test. That is to say, for the sake of simple answers/explanations, there's no need to overcomplicate the above scenario with contrived what-ifs around maintenance of the stub and whatnot.
Thanks in advance.
My answers to your specific questions:
Would it be redundant to also use a mock in the above unit test?
As the unit test is written right now it would be redundant but my see answer to your second question below.
What would be the value (if any) in additionally doing something like this in the above unit test?
It think this is the way you should be doing your tests and I would recommend getting rid of your stub, RecruiterStandIn. Instead I would setup the recruit to return canned answers so you don't have to maintain two classes just to return some predefined data:
#Spy
private Recruiter recR;
public void testGrowTeam( ) {
// Setup canned data return
doReturn(generateTestEmployee()).when(recR).srcEmployee(any(Object.class));
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
FYI the above syntax would be for using Mockito. From what I can tell in your case Mockito gives you the power of stubbing out certain parts and much more without requiring you to create new test entities.
Original Answer
Definitely yes you should be doing mock object tests. Mocks Aren't Stubs. Mock object testing allows you to test the interactions between your classes and ensure that things are interacting with the world around them correctly. I think there is less value in these tests when you first write the classes and their corresponding tests. Mock object tests shine a year down the road when a new developer comes in and inadvertently your breaks code because she didn't understand that certain internal behavior was needed..
A somewhat contrived example would be if let's say we had a Car that needed to fill up some gas:
public class Car {
public void fuelUp()
}
Now with standard unit tests we would check that after calling fuelUp() the car was full of gas and that the proper amount of money was deducted from the driver. But since we never tested how fuelUp() was interacting with the world around it, it could easily be doing the following:
public void fueldUp() {
siphonGasFromNearestCar();
buyCoffeeAndChips()
}
But with mock object testing you can ensure that the Car is getting filled up in the proper and expected way.
Its being a few months since I am working with java legacy code, this are some of the things I am dealing with:
0% test coverage.
Huge functions in occasions I even saw some with more than 300 lines of code.
Lots of private methods and in occasions static methods.
Highly tight coupled code.
At the beginning I was very confused, I found difficult to use TDD in the legacy. After doing katas for weeks and practicing my unit testing and mocking skills, my fear has decreased and I feel a bit more confident. Recently I discovered a book called: working effectivelly with legacy, I didn't read it, I just had a look at the table of contents and I discovered something that is new for me, The Seams. Apparently this is very important when working in the legacy.
I think that this Seams could help me alot in breaking dependencies and make my code testeable so I can increase the code coverage and make my unit testing more precise.
But I have a lot of doubts:
Can somebody explain me the difference between a seam and a mock?
Do Seams, break TDD rules in what regards not touching production code, before is tested?
Could you show me some simple example that compares a Seam and a Mock?
Below I would like to paste an example I did today where I tried to break a dependency with the goal of making the code testeable and finally increasing test coverage. I would appreciate if you could comment a bit if you see some mistakes?
This is how the legacy code looked like at the beginning:
public class ABitOfLegacy
{
private String sampleTitle;
String output;
public void doSomeProcessing(HttpServletRequest request) {
String [] values = request.getParameterValues(sampleTitle);
if (values != null && values.length > 0)
{
output = sampleTitle + new Date().toString() + values[0];
}
}
}
If I just add a unit test that calls that method and asserts that variable output, has a certain value after the call,then I would be making a mistake, because I am not unit testing, I would be doing integration testing. So what I need to do, Is get rid of the dependency I have in the parameter. To do So, I replace the parameter with an interface:
public class ABitOfLegacy
{
private String sampleTitle;
String output;
public void doSomeProcessing(ParameterSource request) {
String [] values = request.getParameters(sampleTitle);
if (values != null && values.length > 0)
{
output = sampleTitle + new Date().toString() + values[0];
}
}
}
This is how the interface looks like:
public interface ParameterSource {
String[] getParameters(String name);
}
The next thing I do, is create my own implementation of that interface but I include the HttpServletRequest as a global variable and I implement the method of the interface using the method/s of HttpServletRequest:
public class HttpServletRequestParameterSource implements ParameterSource {
private HttpServletRequest request;
public HttpServletRequestParameterSource(HttpServletRequest request) {
this.request = request;
}
public String[] getParameters(String name) {
return request.getParameterValues(name);
}
}
Until this point, I think that all the modifications on the production code were safe.
Now I create the Seam in my test package. If I understood well, now I am able to safely change the behavoir of the Seam. This is how I do it:
public class FakeParameterSource implements ParameterSource {
public String[] values = {"ParamA","ParamB","ParamC"};
public String[] getParameters(String name) {
return values;
}
}
And the final step, would be to get support from the Seam, to test the original behavoir of the method.
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import code.ABitOfLegacyRefactored;
import static org.hamcrest.Matchers.*;
public class ABitOfLegacySpecification {
private ABitOfLegacy aBitOfLegacy;
private String EMPTY = null;
#Before
public void initialize() {
aBitOfLegacy = new ABitOfLegacy();
}
#Test
public void
the_output_gets_populated_when_the_request_is_not_empty
() {
FakeParameterSource fakeParameterSource = new FakeParameterSource();
aBitOfLegacy.doSomeProcessing(fakeParameterSource);
assertThat(aBitOfLegacy.output,not(EMPTY));
}
#Test(expected=NullPointerException.class)
public void
should_throw_an_exception_if_the_request_is_null
() {
aBitOfLegacy.doSomeProcessing(null);
}
}
This will give me 100% test coverage.
I appreciate your thoughts:
Did I break the dependency correctly?
Are the unit tests missing something?
What could be done better?
Is this example good enough to help me understand the difference between a Seam and a Mock?
How could a mock help me here if I don't use the Seam?
A seam is a place in the code that you can insert a modification in behavior. You created a seam when you setup injection of your dependency.
One way to take advantage of a seam is to insert some sort of fake. Fake's can be hand-rolled, as in your example, or be created with a tool, like Mockito.
So, a mock is a type of fake, and a fake is often used by taking advantage of a Seam.
As for your tests and the way you broke the dependency, that's pretty much how I would have done it.
Seams
A seam is a place that allows you to modify the behavior without modifying the code.
In your example, the following is an example of an Object seam (if i'm not mistaken). It allows you to pass in a different object without having to change the code. hence it is a type of seam.
public void doSomeProcessing(ParameterSource request) {..}
By making the parameter an abstract type (instead of a concrete class), you have introduced a seam. The seam now allows you to modify the behavior of the method without editing its code - i.e. at the place of invokation, I can pass in a different object and make the method do something else.
Mocks
Now instead of creating your custom fake (creating a subtype of the interface), you could using a Mock framework to do something like this
Mocks also support asserting whether specific methods were called on it, argument matching and other nifty functionality to be consumed by tests. Less test code to maintain. Mocks are primarily used to assert that a specific call is being made to a dependency. In your example, you seem to be in need of a Stub, you just want to return a canned value.
Pardon my rusty JMock..
#Test
public void
the_output_does_not_get_populated_when_the_request_is_empty
() {
Mockery context = new Mockery();
final ParameterSource mockSource = context.mock(ParameterSource.class)
context.checking(new Expectations(){{
oneOf(mockSource).getParameters();
will(returnValue(new string[]{"ParamA","ParamB","ParamC"} );
}});
aBitOfLegacy.populate(mockSource);
assertThat(aBitOfLegacy.output,not(EMPTY));
}
in .Net
var mockSource = new Mock<ParameterSource>();
mockSource.Setup(src => src.GetParameters())
.Returns(new []{"ParamA","ParamB","ParamC"});