Cucumber-serenity not inject Steps - cucumber

I´m using cucumber-selenium to run some integration tests. I manage to create the feature file and the Test class. But once that I´m in my Give method I see that the ScenarioSteps(ProjectMemberSteps) class that I define to talk with the object page is null.
I was expecting to be injected like JBehave does.
public class OrderTest extends StepsLibrary {
#Steps ProjectMemberSteps projectManager;//This one is null
#Before
public void beforeScenarios() throws Exception {
initializeDemoUIServer();
}
#Given("I open the login page")
public void openLoginPage(){
projectManager.openLoginPage();
}
}
This is the Scenario runner class for the test
/**
* Serenity story for login.
*/
#RunWith(CucumberWithSerenity.class)
#CucumberOptions(features="src/test/resources/features/order/order.feature",
glue = Order.BEHAVIOUR_PACKAGE)
public class Order {
public static final String BEHAVIOUR_PACKAGE = "com.behaviour.steps.serenity";
}
This is class ProjectMemberSteps is under steps/serenity/ as the documentation suggest.
I´m using Maven, and the libraries that I´m using are
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-cucumber</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>serenity-junit</artifactId>
</dependency>
<dependency>
<groupId>net.serenity-bdd</groupId>
<artifactId>core</artifactId>
<version>1.0.47</version>
</dependency>
Anyway this particular test I´m running with the IDE and not through Maven, but I was expecting that "ProjectMemberSteps" would be inject as JBehave use to do.
Any idea what´s wrong?
Regards.

I am also a newbie. I don't see any problem with your OrderTest.java class except it is unnecessarily extending a class called StepsLibrary. In Java-Cucumber, I don't extend any other class. Only exception is When
StepDefinition file(your OrderTest.java) delegates method calls to xxxxSteps.java class and which in turn delegates to xxxPageObject.java (which MUST extend PageObject class from Serenity import net.serenitybdd.core.pages.PageObject;)
I assume Before annotation is to repeat a scenario. Instead another alternative is Background keyword to be used in the feature file itself. I don't claim any advantage with this though.
Per me, Your Test Runner class should only give the package in which xxxxStepDefinitions.java resides, simply like glue = {"stepdefinitions"}, curly braces are optional I believe.
The rest looks perfectly OK to me. Including defining
#Steps ProjectMemberSteps projectManager;
Try one more time.

Related

Mocking System class method using testng, mockito and powermock

I am currently writing tests to a legacy code which uses a function System.getenv("some_environment_variable")
I get a problem when I try to mock these variables by using mockito and powermock (used under testng framework)
What I did so far was
#BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
#Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
But when I tried to run the code above i get the following error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object.
So Iv'e read and saw that this error raised when trying to mock a method with mocking the class itself, but this is not the case here.
After toying around with this for quite sometime, here's how I managed to do it.
In a nutshell, in order to get powermockito and TestNG to work with each other you have to do the following (quoting from the blog post whose link is shared below so that the answer is complete and will be useful even if the blog is not available at a later point in time)
Configure TestNG to use the PowerMock object factory : You can do this either via the attribute object-factory in your <suite> tag of your suite xml or via an #org.testng.annotations.ObjectFactory annotated method which returns the powermock's implementation of TestNG interface org.testng.IObjectFactory viz., org.powermock.modules.testng.PowerMockObjectFactory (or) by extending org.powermock.modules.testng.PowerMockTestCase
Use #PrepareForTest to prepare your static class for being mocked by PowerMockito
Please refer to this blog for more details.
Here's a working sample:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.IObjectFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
#PrepareForTest(System.class)
public class SampleTestClass {
#BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
#Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
I used the below dependencies for creating this sample
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
There is another JUnit library which may help you: system-rules, which will allow you to -- among other things -- set and restore environment variables. It is used in conjunction with JUnit #Rules

Mule Issue : More than one JAXBContext

We are facing one issue in our Mule Adapter related to JAXB context, needed some opinion on the same
We are using xpath to evaluate some expressions in the choice blocks in our adapter like below for instance,
<choice doc:name="Choice">
<when expression="//env:abc/env:Body/ref:dataelement/ref:/ref:element" evaluator="xpath">
......
</when>
Now, this works perfectly fine in our application but the problem arises when one of other team uses this Adapter as a jar in their application.
When they try to use this adapter, they are getting below error,
Message : More than one object of type class javax.xml.bind.JAXBContext registered but only one expected.
Type : org.mule.api.registry.RegistrationException
Code : MULE_ERROR--2
JavaDoc : http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/registry /RegistrationException.html.
After debugging with the help of loggers etc, we narrowed down to the choice block used above which is causing this particular issue. Also, googled a bit and found one of the posts pointing out the same issue.
Also, to confirm we commented out the choice block having xpath expression and the flow went ahead but broke again where was xpath used in some other way.
https://www.mulesoft.org/jira/browse/MULE-5926
Can anyone please suggest any suitable workaround to resolve this issue?
I agree with you. It is an unresolved issue in Mule.
One solution we have implemented is not define the jaxb context in the config you are providing in the jar file.
Along with the jar file, give instructions to the end application using it, to include the JAXB packages in their JAXB Context object definition.
This way there will be only one JAXB context and it will work smoothly.
Hope this helps.
This is a bit late however the solution that worked was
<mulexml:jaxb-context name=“JAXB_Context“ packageNames=“org.example.test1:org.example.test2“ doc:name=“JAXB Context1“ />
Please note that there must be no space between package names.
Thanks to: http://dominikbial.de/quicktipp-working-with-more-than-one-package-name-in-a-jaxb-context-config-in-mule-esb/
As of now we cannot add more than one JAXBContext in mule. As an alternative you can write your custom transformer.
I implemented something like
public interface MyAppJaxbObj2XmlComponent<I,O> extends
MyAppComponent<I,O>,Callable {
public O marshal(I input) throws Exception;
}
Abstart transformer
public abstract class AbstractMyAppJaxbObj2XmlComponent<I,O> implements
MyAppJaxbObj2XmlComponent<I,O>{
private Class<I> inputType;
public AbstractMyAppJaxbObj2XmlComponent(){
this.inputType = (Class<I>) new TypeToken<I>(getClass())
{}.getRawType();
}
public AbstractMyAppJaxbObj2XmlComponent(Class<I> type){
this.inputType = type;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
I input = eventContext.getMessage().getPayload(inputType);
O output = marshal(input);
return output;
}
}
Your flow transformer this will load your needed jaxb during startup.
#Component
public class MyFlowJaxbObj2XmlComponent extends
AbstractMyAppJaxbObj2XmlComponent<RequestPayloadType,String> {
#PostConstruct
public void init() {
//Load your schema during startup
}
}
You can also implement a fluid interface as an alternative for this.

exclude metaclass properties for groovy model classes in swagger

How do we exclude metaclass properties in model for "groovy" classes as Response? I have a Jax-Rs resource which returns a groovy object annotated with swagger #ApiModel.
I see too many groovy specific attributes in swagger ui. How do I exclude it from serialization?
#EqualsAndHashCode
#Document(collection = 'MongoCollection')
#CompileStatic
#ToString
#XmlRootElement
#XmlAccessorType(value = XmlAccessType.FIELD)
#ApiModel(value = "Represents a document from mongo collection")
class Foo {
..
..
}
It seems to be using Jackson for pogo-json serialization? How do annotate my groovy class to exclude metaclass properties from getting into json serialized string?
I tried using JsonIgnoreProperties annotation but it didnt help.
#JsonIgnoreProperties(ignoreUnknown = true, value = ["MetaClass","MetaMethod"])
If using springfox, see springfox issues 752, found a way to resolve this :
docket.ignoredParameterTypes(groovy.lang.MetaClass.class)
A code example is:
#Configuration
public class SpringFoxConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.ignoredParameterTypes(groovy.lang.MetaClass.class)
.select()
.apis(RequestHandlerSelectors.any())
.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
.paths(PathSelectors.any())
.build();
}
}
This could be a bug in swagger as per https://github.com/wordnik/swagger-core/issues/519.
I switched from groovy to java classes for model objects to proceed as of now. Will work on creating a test for this issue when I get time.
https://springdoc.org/#groovy-support
Including this dependency with the springdoc-openapi-ui dependency will resolve the issue in the newer versions.
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-groovy</artifactId>
<version>1.6.13</version>
</dependency>
Upgrading Swagger to a version >= 1.3.5 should resolve this.

Jersey 2 - JAXB

Using Jersey 2 m13-3 in Tomcat 7, I'm trying to post XML and have JAXB automatically unmarshal it.
My method signature is something like:
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces( {"text/xml"})
public Response setFoo(
myXJC.generatedclass.Foo foo
)
I get a 400 bad request, but no exception (that I can find).
Testing with:
#POST
#Consumes(MediaType.APPLICATION_XML)
#Produces( {"text/xml"})
public Response setFoo() { ... }
I'm confident this method is being invoked in response to a request.
But as soon as I add arg myXJC.generatedclass.Foo, it isn't.
Do I need something special in my class which extends javax.ws.rs.core.Application to use JAXB? Something ResourceConfig related perhaps? Any extra jersey specific jars?
I see there is a jersey-media-moxy. I'd be happy to get it working with MOXy, but ideally it would also work with Sun/Oracle JAXB.
I've had a look at the source code of:
<dependency>
<groupId>org.glassfish.jersey.examples</groupId>
<artifactId>jaxb</artifactId>
<version>2.0-m13-3</version>
</dependency>
but I'm still having trouble.
Turns out that when I generated the classes from my XSD using XJC, I'd left an incorrect target namespace in there.
The XML I was posting was not namespace qualified, but the generated classes were expecting a namespace.
Once I fixed this, things worked fine.

Mockito methods are not accessible

I have mockito setup on my project with this maven lines:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
I have no problems to use the #Mock annotation but I can't access and use mockito methods like:
when(someMock.someMethod()).thenReturn();
Eclipse just does not recognize them.
Please help.
Try calling Mockito.when(foo.getBar()).thenReturn(baz) and Mockito.verify(foo).getBar(), which won't rely on static imports. Unlike the #Mock annotation, which is technically a class, when and verify are static methods on the Mockito class.
Once you have that working, then try the static imports to which David alluded:
import static org.mockito.Mockito.when; // ...or...
import static org.mockito.Mockito.*; // ...with the caveat noted below.
This will then allow you to use Mockito.when without specifying the Mockito class. You can also use a wildcard, as so, but per this SO answer the Java docs recommend using wildcards sparingly--especially since it can break if a similarly-named static method is ever added to Mockito later.
Adding import org.mockito.*; is insufficient because that adds all classes in the org.mockito package, but not the methods on org.mockito.Mockito.
For Eclipse in particular, you can add a static import by putting the cursor on the when part of Mockito.when and pressing Control-Shift-M ("Add import"). You can also add org.mockito.Mockito to your Favorites (Window > Preferences > Java > Editor > Content Assist > Favorites > New Type) so that all Mockito static methods show up in your Ctrl-Space content assist prompt even if you haven't imported them specifically. (You may also want to do this for org.mockito.Matchers, which are technically available on org.mockito.Mockito via inheritance, but may not show up in Eclipse for that reason.)
Kotlin syntax - dont forget the ` ` backticks:
import org.mockito.Mockito.`when`
`when`(someMock.someMethod()).thenReturn();

Resources