Junit testing for a class with strings - junit

//DOC Datatype Constants
public enum DocDatatype {
PROFILE("Profile"),
SUPPORT_DETAIL("SupportDetail"),
MISC_PAGE("MiscPage"),
String name;
DocDatatype(String name) {
this.name = name;
}
public String getName() {
return name;
}
// the identifierMethod
public String toString() {
return name;
}
// the valueOfMethod
public static DocDatatype fromString(String value) {
for (DocDatatype type : DocDatatype.values()) {
if (type.getName().equals(value))
return type;
}
throw new java.lang.IllegalArgumentException(value
+ " is Not valid dmDataType");
}
}
I have written the junit test case in this way. Whether it is right way to write or wrong way...?
public class DocDatatypeTest {
private static final Log logger = LogFactory
.getLog(TreeConstantTest.class);
#Test
public void testDocDatatypeFromName()
{
DocDatatype d= DocDatatype.fromString("Profile");
assertTrue((d.toString().compareToIgnoreCase("PROFILE") == 0));
}
#Test
public void testDocDatatypeFromName1()
{
DocDatatype d = DocDatatype.fromString("SupportDetail");
assertTrue((d.toString().compareToIgnoreCase("SUPPORT_DETAIL") == 0 ));
}
}
}

A few things here:
Remove the logger from the test. A test should pass or fail, no need for logging
Don't use assertTrue for this. If the test fails it will give you no information about /why/ it failed.
I would change this to
#Test
public void testDocDatatypeFromName()
{
DocDatatype actualDocType = DocDatatype.fromString("Profile");
assertSame(DocDataType.PROFILE, actualDocType);
}
If you really want to assert that value of the toString then do this
#Test
public void testDocDatatypeFromName()
{
DocDatatype d= DocDatatype.fromString("Profile");
assertEquals("Profile", d.toString());
}
You're missing tests for when the lookup doesn't match anything
I wouldn't even write these tests as I see them adding no value whatsoever. The code that uses the enums should have the tests, not these.
Your tests are named very badly. There's no need to start a test with test and the fact you add a "1" to the end of the second test should tell you something. Test names should focus on action and behaviour. If you want to read more about this, get the December issue of JAX Magazine which has a snippet about naming from my forthcoming book about testing.

Related

Unit test for Spring KafkaListener with "Acknowledge" interface as an argument

I'm not expert at unit test but trying to write unit test for :
#KafkaListener(id = "group_id", topics = "topic" )
public AvroObject listen(AvroObject test, Acknowledgment ack)
But no idea how I can make it when there is and interface as an argument. I try this but not sure is it something useful or not make sense as an test :
#InjectMocks
KafkaConsumer kafkaConsumerTest;
#Test
#DisplayName("Assert Valid Consume")
void consumeValidEvent() throws URISyntaxException, IOException, InterruptedException {
// given
AvroObject event = createEvent(); //Create sample object as AvroObject
// when
AvroObject response = kafkaConsumerTest.listen(event, new Acknowledgment() {
#Override
public void acknowledge() {
}
#Override
public void nack(long sleep) {
//do nothing
}
// then
assertNotNull(response);
assertEquals(response.getCode1() ,98765);
assertEquals(response.getCode2() ,123456);
}
I was wondering if you can give me the best approach for this situation! cheers

How to mock a Consumer argument using EasyMock with PowerMock

I have a test scenario where I need to mock a Consumer parameter.
In the following code the startTracer is the method to be tested.
class TracerService {
private TracerController tracerController;
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
...
}
Basically, I want to test if the tracerController.startTracer(param1) is receiving the param1 as argument.
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1));
expectLastCall().once();
...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
How I can configure EasyMock/PowerMock for that executeOnTracerControllerScope execute tracerController.startTracer without invocating their internal code?
tracerController is a mock. So startTracer won't be called on it. As defined right now, it will simply do nothing. The code doing what you are asking should be something like that:
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1)); // no need for the expect, it's the default
replay(tracerController);
// ...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
Of course, attendStartConditions and executeOnTracerControllerScope will be called for real.
Following your comment, if you want to mock executeOnTracerControllerScope, you will do the code below. However, your lambda won't be called anymore. So you won't be able to validate the param.
public class MyTest {
#Test
public void test() {
TracerController tracerController = mock(TracerController.class);
TracerService service = partialMockBuilder(TracerService.class)
.withConstructor(tracerController)
.addMockedMethod("executeOnTracerControllerScope")
.mock();
replay(tracerController);
service.startTracer("tracer", "param");
}
}
class TracerService {
private final TracerController tracerController;
public TracerService(TracerController tracerController) {
this.tracerController = tracerController;
}
public boolean attendStartConditions(String tracerName, Object param1) {
return true;
}
public void executeOnTracerControllerScope(Consumer<TracerController> tracer) {
tracer.accept(tracerController);
}
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
}
interface TracerController {
void startTracer(Object param1);
}

How to run different tests on a single Document variable which was fetched with Jsoup.connect(string)

I have multiple test cases and I want to use a single Document variable with all of them.
There are more test units which will use this Document.
I had an idea to download the html code, in order to avoid connecting to the site multiple times and taking up server resources, but still I think that it wouldn't be an optional approach to testing.
public class ScrapperTest {
public ScrapperTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
/**
* Test of scrapeManufacturer method, of class Scrapper.
*/
#Test
public void testScrapeManufacturer() {
System.out.println("scrapeManufacturer");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeManufacturer(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
}
/**
* Test of scrapeMinPrice method, of class Scrapper.
*/
#Test
public void testScrapeMinPrice() {
System.out.println("scrapeMinPrice");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeMinPrice(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}

How to compare two objects in Junit

I am new to java & Junit. Please help to write Junit test case to test the CargoBO method where Equals & Hashcode functionalities are not implemented.Basically i need to compare 2 objects using Equalbuilder class in junit.
public class CargoBO {
public Cargo cargoDetails(String name,String desc,double length,double width) {
return new Cargo(name,desc,length,width);
}
}
public class CargoJUnit {
Cargo cargo;
#Before
public void createObjectForCargo() {
cargo = new Cargo("audi","des",123.00,234.00);
}
#Test
public void testCargoDetails() {
CargoBO cargoBO = new CargoBO();
//assertTrue(cargo.equals(cargoBO.cargoDetails("audi","des",123.00,234.00)));
Assert.assertEquals(cargo, cargoBO.cargoDetails("audi","des",123.00,234.00));
}
}
Correct test case for your scenario is
#Test
public void testCargoDetails() {
String name = "test name";
String desc = "desc";
double length = 10d;
double width = 100d;
Cargo result = cargoBO.cargoDetails(name, desc, length, width);
Assert.assertEquals(cargo.getName, name);
Assert.assertEquals(cargo.getDesc, desc);
Assert.assertEquals(cargo.getLength, length);
Assert.assertEquals(cargo.getWidth, width);
}
You are testing a method which accepts parameters and calls a constructor passing those parameters.
Your test should be verifying if the given parameters are correctly passed by the method or not.

Repeating TestNG or JUnit test suite

I trying to repeat login_logout.class 10 times. Why can't I repeat this 10 times?
#RunWith(Suite.class)
#SuiteClasses({login_logout.class})
public class AllTests {
#Parameters
public static Collection<Object[]> getData(){
Object[][] data = new Object[10][0];
return Arrays.asList(data);
}
}
My understanding is "new Object[10][0]" is to construct an two-dimension array:
(1) [10][0] mean the array has 10 lines that each line holds zero object
==> Is it supposed to be "[10][1]" ?
(2) As only the code you uploaded, you didn't actually create any real object,
because the "new Object[10][0]" only make an array not any real object
The Suite test runner doesn't support parameters. You could rewrite login_logout as a parameterized test:
#RunWith(Parameterized.class)
public class LoginLogoutTest {
#Parameterized.Parameters
public static Collection<Object[]> values() {
return Arrays.asList(
new Object[10][1]);
}
public LoginLogoutTest(Object ignored) {
}
#Test
public void doSomething() {
}
}
That being said, I can't think of too many use cases for running the exact same test ten times.