I am trying to find the way to test RichFilter function just like RichMappFunction like present here : RichMapFunction Testing is present here......Searched through internet and find nothing...Please help...
public class Person{
public String name;
public Int age;
}
public class OCRKafkaFilter extends RichFilterFunction<Person> {
#Override
public boolean filter(Person person) {
return person.age>21;
}
}
How can we write a test case for this rich filter function for stateful operators ...
You can up a test harness for a filter function doing something like this:
private OCRKafkaFilter function;
private OneInputStreamOperatorTestHarness<Person, Person> harness;
#BeforeEach
void setUpHarness() throws Exception {
function = new OCRKafkaFilter();
StreamFilter<Person> operator = new StreamFilter<>(function);
harness = new OneInputStreamOperatorTestHarness<>(operator);
harness.open();
}
In the example you gave, the RichFilterFunction isn't stateful. In that case you can write tests like this:
public class FilterFunctionTest {
#Test
public void testFilter() {
OCRKafkaFilter filter = new OCRKafkaFilter();
Person person21 = new Person(21);
Person person22 = new Person(22);
assertEquals(false, filter.filter(person21));
assertEquals(true, filter.filter(person22));
}
}
Related
I am using JUNIT5, have been trying to fully coverage a piece of code that involves System.getenv(""); I writed a couple classes to replicate what I am experiencing right now and so you can use them to understand me also (minimal reproducible example):
First we have the service I need to get with full coverage (ServiceToTest.class) (it has a CustomContainer object which contains methods that it needs):
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest() {
Object configuration = new Object();
String envWord = System.getenv("envword");
this.customContainer = new CustomContainer(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}
CustomContainer.class:
public class CustomContainer {
#Getter
String containerName;
Object configuration;
public CustomContainer(Object configuration, String containerName) {
this.configuration = configuration;
this.containerName = containerName;
}
}
I have tried using ReflectionTestUtils to set the envWord variable without success... I tried this https://stackoverflow.com/a/496849/12085680, also tried using #SystemStubsExtension https://stackoverflow.com/a/64892484/12085680, and finally I also tried using Spy like in this answer https://stackoverflow.com/a/31029944/12085680
But the problem is that this variable is inside the constructor so this only executes once and I think that it happens before any of this configs I tried before can apply, here is my test class:
#ExtendWith(MockitoExtension.class)
class TestService {
// I have to mock this becase in real project it has methods which I need mocked behavour
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
// The serviceToTest class in which I use ReflectionTestUtils to use the mock above
// Here is where the constructor gets called and it happens BEFORE (debuged) the setup method
// which is anotated with #BeforeAll
private static ServiceToTest serviceToTest = new ServiceToTest();
#BeforeAll
static void setup() {
// set the field customContainer at serviceToTest class to mockCustomContainer
ReflectionTestUtils.setField(serviceToTest, "customContainer", mockCustomContainer);
}
#Test
void testGetContainerNameNotNull() {
assertNull(serviceToTest.getContainerName());
}
}
I need to write a test in which serviceToTest.getContainerName is not null but the real purpose of this is to have coverage of this sentence envWord == null ? "default" : envWord so it would be a test that is capable of executing the constructor and mocking System.getenv() so that it returns not null...
Right now the coverage looks like this and I can not find a way to make it 100% Any ideas??
EDIT:
So after following tgdavies suggestion, the code can be 100% covered, so this is the way:
Interface CustomContainerFactory:
public interface CustomContainerFactory {
CustomContainer create(Object configuration, String name);
}
CustomContainerFactoryImpl:
#Service
public class CustomContainerFactoryImpl implements CustomContainerFactory {
#Override
public CustomContainer create(Object configuration, String name) {
return new CustomContainer(configuration, name);
}
}
EnvironmentAccessor Interface:
public interface EnvironmentAccessor {
String getEnv(String name);
}
EnvironmentAccessorImpl:
#Service
public class EnvironmentAccessorImpl implements EnvironmentAccessor {
#Override
public String getEnv(String name) {
return System.getenv(name);
}
}
Class ServiceToTest after refactoring:
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest(EnvironmentAccessor environmentAccessor, CustomContainerFactory customContainerFactory) {
Object configuration = new Object();
String envWord = environmentAccessor.getEnv("anything");
this.customContainer = customContainerFactory.create(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}
Finally the test case after refactoring (here is were I think it can be improved maybe?):
#ExtendWith(MockitoExtension.class)
class TestService {
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
private static CustomContainerFactory customContainerFactoryMock = mock(CustomContainerFactoryImpl.class);
private static EnvironmentAccessor environmentAccessorMock = mock(EnvironmentAccessorImpl.class);
private static ServiceToTest serviceToTest;
#BeforeAll
static void setup() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn("hi");
serviceToTest = new ServiceToTest(environmentAccessorMock, customContainerFactoryMock);
ReflectionTestUtils.setField(serviceToTest, "customContainer", mockCustomContainer);
when(serviceToTest.getContainerName()).thenReturn("hi");
}
#Test
void testGetContainerNameNotNull() {
assertNotNull(serviceToTest.getContainerName());
}
#Test
void coverNullReturnFromGetEnv() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn(null);
assertAll(() -> new ServiceToTest(environmentAccessorMock, customContainerFactoryMock));
}
}
Now the coverage is 100%:
EDIT 2:
We can improve the test class and get the same 100% coverage like so:
#ExtendWith(MockitoExtension.class)
class TestService {
private static CustomContainer mockCustomContainer = mock(CustomContainer.class);
private static IContainerFactory customContainerFactoryMock = mock(ContainerFactoryImpl.class);
private static IEnvironmentAccessor environmentAccessorMock = mock(EnvironmentAccessorImpl.class);
private static ServiceToTest serviceToTest;
#BeforeAll
static void setup() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn("hi");
when(customContainerFactoryMock.create(any(), anyString())).thenReturn(mockCustomContainer);
serviceToTest = new ServiceToTest(environmentAccessorMock, customContainerFactoryMock);
}
#Test
void testGetContainerNameNotNull() {
assertNotNull(serviceToTest.getContainerName());
}
#Test
void coverNullReturnFromGetEnv() {
when(environmentAccessorMock.getEnv(anyString())).thenReturn(null);
assertAll(() -> new ServiceToTest(environmentAccessorMock, customContainerFactoryMock));
}
}
Refactor your code to make it testable, by moving object creation and static method calls to components, which you can mock in your tests:
interface ContainerFactory {
CustomContainer create(Object configuration, String name);
}
interface EnvironmentAccessor {
String getEnv(String name);
}
#Service
public class ServiceToTest {
private final CustomContainer customContainer;
public ServiceToTest(ContainerFactory containerFactory, EnvironmentAccessor environmentAccessor) {
Object configuration = new Object();
String envWord = environmentAccessor.getEnv("envword");
this.customContainer = containerFactory.create(configuration, envWord == null ? "default" : envWord);
}
public String getContainerName() {
return customContainer.getContainerName();
}
}
New in JUnit here. I am using JUnit 4 with Mockito. How do I write junit for "if" condition?
Note: I am trying to cover inside the if statement when question is not null. Hopefully my question makes sense.
public class MyClass{
private HttpServletRequest request;
private A a;
private B b;
public void go(String something, String s){
MyQuestion question = Exam.getSubject().getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
// getMarks I do have catching an exception
Here is the snippet:
public class MarksClass{
Public MyQuestion getMarks(long idA, long IdB, String s){
try{
//some code
}catch(Exception e){
throw new SomeException("exception" + e);
}
}
}
Assuming, "getSubject" returns a field with name "subject".
final HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
ReflectionTestUtils.setField(myClass, "request", mockedRequest);
final MarksClass mockedMarksClass = Mockito.mock(MarksClass.class);
final MyQuestion mockedResult = Mockito.mock(MyQuestion.class);
Mockito.when(mockedMarksClass.getMarks(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyString()).thenReturn(mockedResult);
ReflectionTestUtils.setField(myClass, "subject", mockedMarksClass);
//... rest of the test
Design your class in such a way that testing becomes easy. Or change the design so that it can be tested more easily.
Having global singletons makes testing difficult, if not impossible. The general way forward is to have a class injected with all its external dependencies (DI, dependency injection) or pass the dependencies as arguments to the method.
public class MyClass {
private HttpServletRequest request;
private A a;
private B b;
private final Supplier<Subject> subjectFactory;
public MyClass(final Supplier<Subject> subjectFactory) {
this.subjectFactory = subjectFactory;
}
public void go(String something, String s){
final MyQuestion question = subjectFactory.get().getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
Then in your real code, initialize the class with a method reference to the method on your singleton:
final MyClass myClass = new MyClass(Exam::getSubject);
And in your test inject a test double:
new MyClass(() -> new Subject() {
#Override
public MyQuestion getMarks(…) {
return null;
}
);
Of course, nothing is prevent you from changing the Supplier<Subject> to a Supplier<MyQuestion>, Function<String, MyQuestion>, or a custom interface; and then replacing this with a test double.
#FunctionalInterface
public interface Grader {
MyQuestion getMarks(String idA, String idB, String something);
}
public class MyClass {
private HttpServletRequest request;
private A a;
private B b;
private final Grader grader;
public MyClass(final Grader grader) {
this.grader = grader;
}
public void go(String something, String s){
final MyQuestion question = grader.getMarks(a.getAId, b.getBId(), something);
if(question !=null){
request.setAttribute(s, question);
}
}
}
And then again in your production code vs your test code:
final MyClass production = new MyClass(Exam.getSubject()::getMarks);
final MyClass underTest = new MyClass((a, b, something) -> null);
Providing different implementations of this interface can make your code a bit more expressive:
public class ExamSubjectGrader implements Grader {
#Override
public MyQuestion getMarks(String idA, String idB, String something) {
return Exam.getSubject().getMarks(idA, idB, something);
}
}
public class NullGrader implements Grader {
#Override
public MyQuestion getMarks(String idA, String idB, String something) {
return null;
}
}
MyClass production = new MyClass(new ExamSubjectGrader());
MyClass underTest = new MyClass(new NullGrader());
(both of those are actually singletons, but they could have their own dependencies or state).
And as you can see: you don't even need a heavy mocking library such as Mockito. Good ol' Java can do that just fine.
Find more details in the question Why is my class not using my mock in unit test?
I am writing unit test but I am facing an error some how. I am triyng to test my ServiceImpl just showing my entire code down below My code below;
My Service Class
#Service
public class PlaneServiceImpl implements PlaneCallerService {
private final PlaneFactory planeFactory;
public PlaneServiceImpl(PlaneFactory planeFactory) {
this.planeFactory = planeFactory;
}
#Override
public String getPlaneType(String planeType) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(planeFactory.getPlane(planeType).getType());
stringBuilder.append(" Plane has produced.");
return stringBuilder.toString();
}
Plane class down below
public interface Plane {
String getType();
}
My PlaneFactory class down below;
#Component
public class PlaneFactory {
public Plane getPlane(String planeType) {
if (StringUtils.isBlank(planeType)) {
throw new PlaneTypeNotFoundException();
}
if (planeType.equalsIgnoreCase("lightJet")) {
return new LightJet();
} else if (planeType.equalsIgnoreCase("midJet")) {
return new MidJet();
My Mock Test just down below
public class PlaneCallerServiceImplTest {
private PlaneFactory planeFactory;
private PlaneCallerService planeCallerService;
private plane plane;
#Before
public void setUp() {
planeFactory = mock(PlaneFactory.class);
planeCallerService = new PlaneCallerServiceImpl(planeFactory);
plane= mock(Plane.class);
}
#Test
public void testPlaneType() {
String planeType = "";
when(planeFactory.getPlane(planeType)).thenReturn(plane);
String result = planeCallerService.getplaneType(planeType);
assertNotNull(result);
}
}
I'm getting The method getPlane(String) is undefined for the type PlaneFactory
I am quite new for unit test and also mock test any help would be appreciate
Thank you in advanced
Your issue is that from the below statement:
when(planeFactory.getPlane(planeType)).thenReturn(plane);
you are returning a mocked response of type Plane but in that mocked response when you call Plane.getType() that method is not implemented.
You can mock the response of that too, add
when(plane.getType()).thenReturn("SOME_MOCKED_STRING");
This should start to work.
Below is the complete test class:
public class PlaneServiceImplTest {
private PlaneFactory planeFactory;
private PlaneServiceImpl planeCallerService;
#Before
public void setUp() {
planeFactory = mock(PlaneFactory.class);
planeCallerService = new PlaneServiceImpl(planeFactory);
}
#Test
public void testPlaneType() {
Plane plane = mock(Plane.class);
when(planeFactory.getPlane(anyString())).thenReturn(plane);
String result = planeCallerService.getPlaneType("Test");
assertNotNull(result);
}
}
#RunWith(JUnitParamsRunner.class)
public class MySimpleTest {
private MyRec rec;
private Matrix matrix;
#Before
public void createRecognizerBeforeEveryExecution() {
rec = new MyRec();
matrix = MatrixUtils.createMatrixWithValues();
}
public static Iterable<Object[]> data() {
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
#Test
#Parameters(method = "data")
public void test1(String output, String input) {
rec.fun1(matrix);
assertEquals(output, rec.someFunction(input));
}
public static Iterable<Object[]> data2() {
return Arrays.asList(
new Object[]{"expectedothervalue1", "input1"},
new Object[]{"expectedothervalue2", "input2"}
);
}
#Test
#Parameters(method = "data2")
public void test2(String output, String input) {
rec.fun1(matrix);
rec.fun2(matrix);
assertEquals(output, rec.someFunction(input));
}
}
I'm trying to find out what is the proper way to make this test. I'd like to use parametrized test, because it's really convenient way.
So as you can see, in every test function I call some function (fun1 and fun2). But I need to call it only once per every test (e.g. before each parametrized test execution).
Is there any way to tell JUnitParams that it should execute other function before executing all of parametrized tests?
I can't use #Before annotation, because as you can see in test1 I'm not using fun2. It think it should be executed by separate function.
Solution 1:
As fun[1|2] does not depend on internal test state, try to place their invocations inside data and data2 methods accordingly.
public static Iterable<Object[]> data() {
rec.fun1(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
public static Iterable<Object[]> data2() {
rec.fun1(matrix);
rec.fun2(matrix);
return Arrays.asList(
new Object[]{"expectedvalue1", "input1"},
new Object[]{"expectedvalue2", "input2"}
);
}
Solution 2:
Spliting test cases is not a best practice. Your test are harder to maintain. Flow is far more complicated. There is also a risk your tests start depends on each other. Duplication in tests sometimes is simply better.
PS:
If you are using Strings as test method parameters it's better to pass them exactly like in 25th line of this file:
https://github.com/Pragmatists/JUnitParams/blob/master/src/test/java/junitparams/usage/SamplesOfUsageTest.java instead of special methods.
#Test
#Parameters({"AAA,1", "BBB,2"})
public void paramsInAnnotation(String p1, Integer p2) { }
I decided to use TestNG to resolve this problem (code just to show my train of thought):
import org.testng.Assert;
import org.testng.annotations.*;
import java.lang.reflect.Method;
public class TempTest {
private Integer number;
#BeforeMethod
public void init(Method m) {
number = 5;
switch(m.getName()) {
case "test2":
fun(10);
fun2(5);
break;
case "test1":
fun(10);
break;
}
}
public void fun(int value) {
number += value;
}
public void fun2(int value) {
number -= value;
}
#Test
public void test1() {
Assert.assertEquals(new Integer(15), number);
}
#Test
public void test2() {
Assert.assertEquals(new Integer(10), number);
}
#Test
public void test3() {
Assert.assertEquals(new Integer(5), number);
}
}
I am new to JUnit and facing difficulty in writing JUnit.
I have an interface and a class
Interface
public interface Student{
List<String> getStudentList();
void setStudentList(List<String> studentList);
void createStudentList();
}
Class
public class StudentServiceImpl implements Student{
private List<String> studentList
public List<String> getStudentList() {
return studentList;
}
public void setStudentList(final List<String> studentList){
this.studentList = studentList;
}
public void createStudentList(){
if (studentList == null) {
studentList = new ArrayList<String>();
studentList.add("John");
studentList.add("Bill");
studentList.add("Ricky");
studentList.add("Jack");
}
setStudentList(studentList);
}
}
What is the best to write Junit for above class. What should be kept in mind while writing JUnit cases. Can somebody help me?
Here is an example of IMHO well-written test case (written in notepad, please correct if does not compile):
import static org.fest.assertions.Assertions.assertThat;
public class StudentTest {
private final Student student = new StudentServiceImpl();
#Test
public void shouldReturnEmptyListOfStudentsWhenNotInitialized() {
//given
//when
List<String> students = student.getStudentList();
//then
assertThat(students).isEmpty();
}
#Test
public void shouldReturnSomeStudentsWhenListCreated() {
//given
student.createStudentList();
//when
List<String> students = student.getStudentList();
//then
assertThat(students).containsExactly("John", "Bill", "Ricky", "Jack");
}
#Test
public void shouldStorePreviouslySetListOfStudents() {
//given
student.setStudentList(Arrays.asList("Jane", "Bob"));
//when
List<String> students = student.getStudentList();
//then
assertThat(students).containsExactly("Jane", "Bob");
}
}
Few tips:
Keep tests short and simple
Test name should describe what use case is being tested
Separate setup code, tested logic and assertions
Code should be easy to read. Use fluent and descriptive libraries like FEST
Further improvements:
The first test should fail, do you know why?
There are still few tests missing, do you know which ones?