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

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.");
}

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 do I make a JMS ObjectMessage for a Unit Test?

I'm trying to write a unit test for an MDB. The goal of my test is to make sure that the logic in the MDB can identify the correct type of object in the ObjectMessage and process it. However, I can't figure out how to make an ObjectMessage so I can test it. I keep getting null pointer exceptions.
Here is my unit test:
/**
* Test of the logic in the MDB
*/
#RunWith(JMockit.class)
#ExtendWith(TimingExtension.class)
class MDBTest
{
protected MyMDB mdb;
#BeforeEach
public void setup() throws NamingException, CreateHeaderException, DatatypeConfigurationException, PropertiesDataException
{
mdb = new MyMDB();
}
/**
* Test the processing of the messages by the MDB
*/
#Test
void testReceivingMessage() throws JMSException, IOException
{
MyFirstObject testMsg = getTestMessage();
ObjectMessage msg = null;
Session session = null;
new MockUp<ObjectMessage>()
{
#Mock
public void $init()
{
}
#Mock
public Serializable getObject()
{
return testMsg;
}
};
new MockUp<Session>()
{
#Mock
public void $init()
{
}
#Mock
public ObjectMessage createObjectMessage(Serializable object)
{
return msg;
}
};
// !!!! Null pointer here on Session !!!!
ObjectMessage msgToSend = session.createObjectMessage(testMsg);
mdb.onMessage(msgToSend);
assertEquals(1, mdb.getNumMyFirstObjectMsgs());
}
/**
* Create a Test Message
*
* #return the test message
* #throws IOException
*/
protected MyFirstObject getTestMessage) throws IOException
{
MyFirstObject myObj = new MyFirstObject();
myObj.id = 0123;
myObj.description = "TestMessage";
return myObj;
}
}
I feel like I should be able to initialize Session somehow, but I need to do it without using an additional library like Mockrunner.
Any suggestions?
I would try to address this in a different style. Provide a mock client, that will just mock the right API.
We should mock only a set of functions required for message retrieval and processing but that means we might have to provide a custom implementation for some of the APIs available in the EJB/JMS library. The mock client will have a function to push messages on a given topic/queue/channel, message can be simple String.
A simple implementation might look like this, in this other methods have been omitted for simplicity.
// JMSClientImpl is an implementation of Connection interface.
public class MyJmsTestClient extends JMSClientImpl{
Map<String, String> channelToMessage = new ConcurrentHashMap<>();
public Map<String, String> getMessageMap(){
return channelToMessage;
}
public void enqueMessage(String channel, String message){
channelToMessage.put(channe, message);
}
#Override
public Session createSession(){
return new MyTestSession(this);
}
}
// A class that implements some of the methods from session interface
public MyTestSession extends SessionImpl{
private MyJmsTestClient jmsClient;
MyTestSession(MyJmsTestClient jmsClient){
this.jmsClient = jmsClient;
}
// override methods that fetches messages from remote JMS
// Here you can just return messages from MyJmsTestClient
// override other necessary methods like ack/nack etc
MessageConsumer createConsumer(Destination destination) throws JMSException{
// returns a test consume
}
}
A class that implements methods from MessageConsumer interface
class TestMessageConsumer extends MessageConsumerImpl {
private MyJmsTestClient jmsClient;
private Destination destination;
TestMessageConsumer(MyJmsTestClient jmsClient, Destination destination){
this.jmsClient = jmsClient;
this.destination = destination;
}
Message receive() throws JMSException{
//return message from client
}
}
There's no straight forward, you can see if there're any library that can provide you embedded JMS client feature.

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);
}

Lifecycle of #After method

I am trying to gather some information after every test method, and would like to analyze the gathered information after the test class completes. So, I have a private member variable, a list which I would like to add to after every test method completes. However, at the end of the day, the member variable always remains null.
Note: My test class implements Callable interface.
Here is my code snippet:
{
private List<String statisticsCollector;
private JUnitCore core = null;
private int x = 0;
public MyLoadTest() {
this.core = new JUnitCore();
this.statisticsCollector = new ArrayList<String>();
}
#Override
public List<String> call() {
log.info("Starting a new thread of execution with Thread# -" + Thread.currentThread().getName());
core.run(this.getClass());
return getStatisticsCollector(); // this is always returing a list of size 0
}
#After
public void gatherSomeStatistics() {
x = x+1;
String sb = new String("Currently executing ----" + x);
log.info("Currently executing ----" + x);
addToStatisticsCollector(sb);
}
#Test
#FileParameters(value = "classpath:folder/testB.json", mapper = MyMapper.class)
public void testB(MarsTestDefinition testDefinition) {
runTests(testDefinition);
}
#Test
#FileParameters(value = "classpath:folder/testA.json", mapper = MyMapper.class)
public void testA(MyDefinition testDefinition) {
runTests(testDefinition);
}
public List<String> getStatisticsCollector() {
return this.statisticsCollector;
}
public void addToStatisticsCollector(String sb) {
this.statisticsCollector.add(sb);
}
}
So, why is it always getting reset, even though I am appending to the list in my #After annotated method?
Any help will be highly appreciated. Thanks
Try with following code, is it working ?
private static List<String> statisticsCollector = new ArrayList<String>();
private JUnitCore core = null;
private int x = 0;
public MyLoadTest() {
this.core = new JUnitCore();
}
public List<String> getStatisticsCollector() {
return statisticsCollector;
}

Junit testing for a class with strings

//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.