I'm trying to figure out how org.mockito.AdditionalMatchers works but I failed. Why is this test failing?
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.*;
import static org.mockito.AdditionalMatchers.*;
public class DemoTest {
#Test
public void testGreaterThan() throws Exception {
assertThat( 17
, is( gt( 10 ) )
);
}
}
Output is:
java.lang.AssertionError:
Expected: is <0>
got: <17>
You should use Hamcrest's greaterThan for this case. gt is for verifying arguments of method calls in mock objects:
public class DemoTest {
private List<Integer> list = Mockito.mock(List.class);
#Test
public void testGreaterThan() throws Exception {
assertThat(17, is(org.hamcrest.Matchers.greaterThan(10)));
list.add(17);
verify(list).add(org.mockito.AdditionalMatchers.gt(10));
}
}
Related
In the test class trying to test the main method and not sure how to use the mock object here.
How to use the mock object orders to call the main method and it's methods inside the main method
Any suggestions on how this can be done?
public class Orders {
public static void main(String[] s) {
Orders jp = new Orders();
jp.method1();
List<OrderItems> lstOrdItms = jp.getListOrderItems();
jp.processOrderItems( lstOrdItms );
}
public void method1(List<OrderItem> lstOrderItem) {
.........
}
public List<OrderItem> getListOrderItems() {
............
}
public void processOrderItems() {
............
}
}
public class OrdersTest {
#Mocks
Orders orders;
.....
#Before
public void setUp() {
........
}
#Test
public void testMain() throws SQLException {
// Not sure how to test here
// This will actually execute the main method instead of mock.
orders.main(new String[]{});
}
}
I'm looking at running Cucumber tests with TestNG. However I am having a issue where all my Scenario are running as one TestNG #Test session. Is there a way to run each Scenario as a separate #Test sessions?
Here is my TestNG xml:
<suite name="cucumber Suites">
<test name="cucumber-testing">
<classes>
<class name="runners.Run2" />
</classes>
</test>
</suite>
This will call run the following Test class:
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import cucumber.api.CucumberOptions;
import cucumber.api.testng.AbstractTestNGCucumberTests;
import cucumber.api.testng.CucumberFeatureWrapper;
import cucumber.api.testng.TestNGCucumberRunner;
#CucumberOptions( features="cucumber/features/example.feature",
glue="steps",
format={"pretty"}
)
public class Run2 extends AbstractTestNGCucumberTests{
private TestNGCucumberRunner tcr;
#BeforeClass(alwaysRun=true)
public void beforeClass() throws Exception{
tcr = new TestNGCucumberRunner(this.getClass());
}
#Test(groups="cucumber", description="Runs CucumberFeature", dataProvider="features")
public void feature(CucumberFeatureWrapper cucumberFeature){
tcr.runCucumber(cucumberFeature.getCucumberFeature());
}
#DataProvider
public Object[][] features(){
return tcr.provideFeatures();
}
#AfterClass (alwaysRun=true)
public void afterClass(){
tcr.finish();
}
}
I am wondering if there is a way to get the #DataProviderto provide Scenario and the #Test to run Scenario instead of the features?
The reason for this is that I have other TestNG tests with Listeners and that I want to use the same Listeners, reporting for Cucumber tests.
Thanks
What you can try is providing a specific test name for each feature:
#CucumberOptions( features="cucumber/features/example.feature",
glue="steps",
format={"pretty"}
)
public class Run2 extends AbstractTestNGCucumberTests implements ITest {
private TestNGCucumberRunner tcr;
private String featureName;
#BeforeClass(alwaysRun = true)
public void beforeClass() throws Exception {
tcr = new TestNGCucumberRunner(this.getClass());
}
#BeforeMethod
public void beforeMethod(Object[] params) {
CucumberFeatureWrapper cucumberFeature = (CucumberFeatureWrapper) params[0];
featureName = cucumberFeature.getCucumberFeature().getGherkinFeature().getName();
}
#Test(groups = "cucumber", description = "Runs CucumberFeature", dataProvider = "features")
public void feature(CucumberFeatureWrapper cucumberFeature) {
tcr.runCucumber(cucumberFeature.getCucumberFeature());
}
#Override
public String getTestName() {
return featureName;
}
#DataProvider
public Object[][] features() {
return tcr.provideFeatures();
}
#AfterClass(alwaysRun = true)
public void afterClass() {
tcr.finish();
}
}
Let me know if it is the way you'd like.
Did you already try:
#CucumberOptions( features="cucumber/features/example.feature",
glue="steps",
format={"pretty"}
)
public class Run2 extends AbstractTestNGCucumberTests{
private TestNGCucumberRunner tcr;
#BeforeClass(alwaysRun=true)
public void beforeClass() throws Exception{
tcr = new TestNGCucumberRunner(this.getClass());
}
#Test(groups="cucumber", description="Runs CucumberFeature")
public void scenario(){
for (CucumberFeatureWrapper cucumberFeature : tcr.provideFeatures()) {
tcr.runCucumber(cucumberFeature.getCucumberFeature());
}
}
#AfterClass (alwaysRun=true)
public void afterClass(){
tcr.finish();
}
}
The answer is "Yes", you can run each scenario in cucumber as a test using TestNG.
How? It's explained below:
First of all update your Cucumber Maven dependencies from info.cukes to io.cucumber dependencies
Then instead of using method "provideFeatures()" of "TestNGCucumberRunner" in 'your' following code:
#DataProvider
public Object[][] features(){
return tcr.provideFeatures();
}
Use "provideScenarios()" method in #DataProvider.
The following Java code in Cucumber Runner Class worked perfectly for me to run each scenario as TestNG test in feature files:
public class TestRunner {
private TestNGCucumberRunner testNGCucumberRunner;
#BeforeClass(alwaysRun = true)
public void setUpClass() throws Exception {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
}
#Test(groups = "cucumber scenarios", description = "Runs Cucumber
Scenarios", dataProvider = "scenarios")
public void scenario(PickleEventWrapper pickleEvent, CucumberFeatureWrapper
cucumberFeature) throws Throwable{
testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
}
#DataProvider
public Object[][] scenarios() {
return testNGCucumberRunner.provideScenarios();
}
#AfterClass(alwaysRun = true)
public void tearDownClass() throws Exception {
testNGCucumberRunner.finish();
}
}
I would be happy to see your problem resolved.
Reference: https://github.com/cucumber/cucumber-jvm/blob/master/testng/README.md
I followed this approach: https://github.com/cucumber/cucumber-jvm/blob/master/examples/java-calculator-testng/src/test/java/cucumber/examples/java/calculator/RunCukesByCompositionTest.java
One of the interactions I want to test is that a class Foo is supposed to pass a Stream<Changes> to FooListener.someChangesHappened. Is there a Mockito idiom to verify that a stream contained the expected objects?
Assuming you are just verifying the argument to a mock implementation, and are not actually using it, here is a custom Hamcrest Matcher that will get the job done. It gets hairy when you need to read from the Stream more than once, because Streams are not built for that. You'll notice that this solution even needs to protect itself from JUnit calling matches more than once.
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.verify;
#RunWith(MockitoJUnitRunner.class)
public class Foo {
#Mock
FooListener fooListener;
#Before
public void happen() {
fooListener.someChangesHappened(Stream.of(Changes.ONE, Changes.TWO, Changes.THREE));
}
#Test
public void contains() {
verify(fooListener).someChangesHappened(argThat(streamThat(hasItem(Changes.TWO))));
}
#Test
public void doesNotContain() {
verify(fooListener).someChangesHappened(argThat(streamThat(not(hasItem(Changes.FOUR)))));
}
private static <T> Matcher<Stream<T>> streamThat(Matcher<Iterable<? super T>> toMatch) {
return new IterableStream<>(toMatch);
}
private interface FooListener {
void someChangesHappened(Stream<Changes> stream);
}
private enum Changes {
ONE, TWO, THREE, FOUR
}
private static class IterableStream<T> extends TypeSafeMatcher<Stream<T>> {
Matcher<Iterable<? super T>> toMatch;
List<T> input = null;
public IterableStream(Matcher<Iterable<? super T>> toMatch) {
this.toMatch = toMatch;
}
#Override
protected synchronized boolean matchesSafely(Stream<T> item) {
// This is to protect against JUnit calling this more than once
input = input == null ? item.collect(Collectors.toList()) : input;
return toMatch.matches(input);
}
#Override
public void describeTo(Description description) {
description.appendText("stream that represents ");
toMatch.describeTo(description);
}
}
}
My JAXB parser suddenly stopped working today. It was working for several weeks. I get the following message. I haven't changed this code for several weeks. Wondering if this set up is good.
EDIT 2: Please could somebody help me! I can't figure this out.
EDIT 1:
My acceptance tests running the same code below are working fine. I believe this is a
classloading issue. I am using the JAXB and StAX in the JDK. However, when I deploy to jboss 5.1, I get the error below. Using 1.6.0_26 (locally) and 1.6.0_30 (dev server). Still puzzling over a solution.
unexpected element (uri:"", local:"lineEquipmentRecord"). Expected
elements are
<{}switchType>,<{}leSwitchId>,<{}nodeAddress>,<{}leId>,<{}telephoneSuffix>,<{}leFormatCode>,<{}groupIdentifier>,<{}telephoneNpa>,<{}telephoneLine>,<{}telephoneNxx>
Here is my unmarshalling class:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
public class PartialUnmarshaller<T> {
XMLStreamReader reader;
Class<T> clazz;
Unmarshaller unmarshaller;
public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
this.clazz = clazz;
this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
#Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getMessage());
return true;
}
});
this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
/* ignore headers */
skipElements(XMLStreamConstants.START_DOCUMENT);
/* ignore root element */
reader.nextTag();
/* if there's no tag, ignore root element's end */
skipElements(XMLStreamConstants.END_ELEMENT);
}
public T next() throws XMLStreamException, JAXBException {
if (!hasNext())
throw new NoSuchElementException();
T value = unmarshaller.unmarshal(reader, clazz).getValue();
skipElements(XMLStreamConstants.CHARACTERS, XMLStreamConstants.END_ELEMENT);
return value;
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public void close() throws XMLStreamException {
reader.close();
}
private void skipElements(Integer... elements) throws XMLStreamException {
int eventType = reader.getEventType();
List<Integer> types = new ArrayList<Integer>(Arrays.asList(elements));
while (types.contains(eventType))
eventType = reader.next();
}
}
This class is used as follows:
List<MyClass> lenList = new ArrayList<MyClass>();
PartialUnmarshaller<MyClass> pu = new PartialUnmarshaller<MyClass>(
is, MyClass.class);
while (pu.hasNext()) {
lenList.add(pu.next());
}
The XML being unmarshalled:
<?xml version="1.0" encoding="UTF-8"?>
<lineEquipment>
<lineEquipmentRecord>
<telephoneNpa>333</telephoneNpa>
<telephoneNxx>333</telephoneNxx>
<telephoneLine>4444</telephoneLine>
<telephoneSuffix>1</telephoneSuffix>
<nodeAddress>xxxx</nodeAddress>
<groupIdentifier>LEN</groupIdentifier>
</lineEquipmentRecord>
<lineEquipmentRecord>
<telephoneNpa>111</telephoneNpa>
<telephoneNxx>111</telephoneNxx>
<telephoneLine>2222</telephoneLine>
<telephoneSuffix>0</telephoneSuffix>
<nodeAddress>xxxx</nodeAddress>
<groupIdentifier>LEN</groupIdentifier>
</lineEquipmentRecord>
</lineEquipment>
Finally, here is MyClass:
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
* This class is used as an envelope to hold Martens
* line equipment information.
* #author spgezf
*
*/
#XmlRootElement(name="lineEquipmentRecord")
public class MyClass {
private String telephoneNpa;
private String telephoneNxx;
private String telephoneLine;
private String telephoneSuffix;
private String nodeAddress;
private String groupIdentifier;
public MyClass(){
}
// Getters and Setters.
#XmlElement(name="telephoneNpa")
public String getTelephoneNpa() {
return telephoneNpa;
}
public void setTelephoneNpa(String telephoneNpa) {
this.telephoneNpa = telephoneNpa;
}
#XmlElement(name="telephoneNxx")
public String getTelephoneNxx() {
return telephoneNxx;
}
public void setTelephoneNxx(String telephoneNxx) {
this.telephoneNxx = telephoneNxx;
}
#XmlElement(name="telephoneLine")
public String getTelephoneLine() {
return telephoneLine;
}
public void setTelephoneLine(String telephoneLine) {
this.telephoneLine = telephoneLine;
}
#XmlElement(name="telephoneSuffix")
public String getTelephoneSuffix() {
return telephoneSuffix;
}
public void setTelephoneSuffix(String telephoneSuffix) {
this.telephoneSuffix = telephoneSuffix;
}
#XmlElement(name="nodeAddress")
public String getNodeAddress() {
return nodeAddress;
}
public void setNodeAddress(String nodeAddress) {
this.nodeAddress = nodeAddress;
}
#XmlElement(name="groupIdentifier")
public String getGroupIdentifier() {
return groupIdentifier;
}
public void setGroupIdentifier(String groupIdentifier) {
this.groupIdentifier = groupIdentifier;
}
}
Thanks, this is classloading issue I couldn't overcome so I abandoned JAXB.
Your PartialUnmarshaller code worked for me. Below is an alternate version that changes the skipElements method that may work better.
import java.io.InputStream;
import java.util.NoSuchElementException;
import javax.xml.bind.*;
import javax.xml.stream.*;
public class PartialUnmarshaller<T> {
XMLStreamReader reader;
Class<T> clazz;
Unmarshaller unmarshaller;
public PartialUnmarshaller(InputStream stream, Class<T> clazz) throws XMLStreamException, FactoryConfigurationError, JAXBException {
this.clazz = clazz;
this.unmarshaller = JAXBContext.newInstance(clazz).createUnmarshaller();
unmarshaller.setEventHandler(new ValidationEventHandler() {
#Override
public boolean handleEvent(ValidationEvent event) {
System.out.println(event.getMessage());
return true;
}
});
this.reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
/* ignore headers */
skipElements();
/* ignore root element */
reader.nextTag();
/* if there's no tag, ignore root element's end */
skipElements();
}
public T next() throws XMLStreamException, JAXBException {
if (!hasNext())
throw new NoSuchElementException();
T value = unmarshaller.unmarshal(reader, clazz).getValue();
skipElements();
return value;
}
public boolean hasNext() throws XMLStreamException {
return reader.hasNext();
}
public void close() throws XMLStreamException {
reader.close();
}
private void skipElements() throws XMLStreamException {
while(reader.hasNext() && !reader.isStartElement()) {
reader.next();
}
}
}
I am trying to create an action in which the server needs to response an array list of objects over the wire to the client through GWTP Action.
Category class
package com.business.share;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Id;
public class Category implements Serializable{
Long id;
protected String name;
protected String description;
protected boolean status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public boolean getStatus() {
return status;
}
public void setStatus(boolean status) {
this.status = status;
}
}
GetCategories class
package com.business.client.action;
import java.util.ArrayList;
import com.gwtplatform.dispatch.shared.ActionImpl;
import com.business.client.action.GetCategoriesResult;
import com.business.share.Category;
public class GetCategories extends ActionImpl<GetCategoriesResult> {
private ArrayList<Category> categories;
#SuppressWarnings("unused")
public GetCategories() {
// For serialization only
}
public GetCategories(ArrayList<Category> categories) {
this.categories = categories;
}
public ArrayList<Category> getCategories() {
return categories;
}
}
GetCategoriesResult class
package com.business.client.action;
import java.util.ArrayList;
import com.gwtplatform.dispatch.shared.Result;
import com.business.share.Category;
public class GetCategoriesResult implements Result {
private ArrayList<Category> categories;
#SuppressWarnings("unused")
private GetCategoriesResult() {
// For serialization only
}
public GetCategoriesResult(ArrayList<Category> categories) {
this.categories = categories;
}
public ArrayList<Category> getCategories() {
return categories;
}
}
GetCategoriesActionHandler class
package com.business.server.handler;
import java.util.ArrayList;
import com.gwtplatform.dispatch.server.actionhandler.ActionHandler;
import com.business.client.action.GetCategories;
import com.business.client.action.GetCategoriesResult;
import com.business.share.Category;
import com.google.inject.Inject;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Query;
import com.gwtplatform.dispatch.server.ExecutionContext;
import com.gwtplatform.dispatch.shared.ActionException;
public class GetCategoriesActionHandler implements
ActionHandler<GetCategories, GetCategoriesResult> {
#Inject
public GetCategoriesActionHandler() {
}
#Override
public GetCategoriesResult execute(GetCategories action,
ExecutionContext context) throws ActionException {
ArrayList<Category> categories = new ArrayList<Category>();
// dummy data
Category cat1 = new Category();
cat1.setName("cat1");
cat1.setDescription("cat1 desc");
cat1.setStatus(true);
Category cat2 = new Category();
cat1.setName("cat2");
cat1.setDescription("cat2 desc");
cat1.setStatus(false);
categories.add(cat1);
categories.add(cat2);
return new GetCategoriesResult(categories);
}
#Override
public void undo(GetCategories action, GetCategoriesResult result,
ExecutionContext context) throws ActionException {
}
#Override
public Class<GetCategories> getActionType() {
return GetCategories.class;
}
}
And this is a piece of code in CategoryPresenter, which sends async to server.
#Override
protected void onReset() {
super.onReset();
GetCategories getCategoriesAction = new GetCategories();
dispatchAsync.execute(getCategoriesAction, getCategoriesCallback);
}
private final AsyncCallback<GetCategoriesResult> getCategoriesCallback =
new AsyncCallback<GetCategoriesResult>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(GetCategoriesResult result) {
getView().getCategoryListBox().clear();
ArrayList<Category> categories = result.getCategories();
for(Category category : categories) {
getView().getCategoryListBox().addItem(category.getName());
}
}
};
I don't know what wrong with this piece of code, but GWT compiler always gives error like this.
Compiling module com.business.Business
Validating newly compiled units
Ignored 3 units with compilation errors in first pass.
Compile with -strict or with -logLevel set to TRACE or DEBUG to see all errors.
Finding entry point classes
[ERROR] Errors in 'file:/.blah..blah..blah../businessapp/src/com/business/client/presenter/CategoryPresenter.java'
[ERROR] Line 75: No source code is available for type com.business.share.Category; did you forget to inherit a required module?
[ERROR] Errors in 'file:/.blah..blah..blah../businessapp/src/com/business/client/action/GetCategoriesResult.java'
[ERROR] Line 11: No source code is available for type com.business.share.Category; did you forget to inherit a required module?
[ERROR] Unable to find type 'com.business.client.Business'
[ERROR] Hint: Previous compiler errors may have made this type unavailable
[ERROR] Hint: Check the inheritance chain from your module; it may not be inheriting a required module or a module may not be adding its source path entries properly
Following this error message, it means, com.business.share.Category is not found, but this file is physically stored in that package already. I don't understand why GWT could not find it. I noticed anywhere that I make call Category class, it brings this error always.
Somebody's got an idea on what's going on?
[EDIT]
The problem is solved.
In my Business.gwt.xml, I have
<source path='shared'/>
But my share package is com.business.share (without d)
I just rename the package name from share to shared.
Try to add an empty constructor to the Category class.