TestNG DataProvider marks as invalid return type Iterator<CustomObject>, but it passes the params into a test method - intellij-idea

When creating a Dataprovider that returns Iterator I have it in my test method, but my intellij-idea marks this return type as invalid and shows the message:
"Data provider must return either Object[][] or Iterator[], or Iterator".
Here is my class/ method:
public class TradeTestDataProvider {
#DataProvider(name = "experimental")
public Iterator<TestCase> createCases() throws IOException {
List<TestCase> test = DataReader.generateCasesFromJson("src/test/resources/json/experimental_test_case");
return test.iterator();
}
}
Please advise, if I am missing something or it is related to TestNG/IDE issue?
Update:
I created a post to discuss this issue with plugin:
topic

Related

Error when running my first pact-jvm test

I'm new to contract Testing Automation and I've written my first test using jvm-pact. I'm using junit5.
Below is the code
#ExtendWith(PactConsumerTestExt.class) #PactTestFor(providerName = "testProvider", port = "8081") public class ConsumerTests {
public static final String EXPECTED_BODY = "/integration/stubs/team_members/SingleTeamMember.json";
#Pact(consumer = "testConsumer" , provider="testProvider")
public RequestResponsePact singleTeamMemberSuccess(PactDslWithProvider builder) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
return builder
.given("I have at least one team member")
.uponReceiving("a request for a single team member")
.path("/team-members/1")
.method("GET")
.willRespondWith()
.status(200)
.headers(headers)
.body(EXPECTED_BODY)
.toPact();
}
#Test
#PactTestFor(pactMethod = "singleTeamMemberSuccess")
void testSingleTeamMemberSuccess(MockServer mockServer) throws IOException {
HttpResponse httpResponse = (HttpResponse) Request.Get(mockServer.getUrl() + "/team-members/1")
.execute().returnResponse();
assertThat(httpResponse.getStatusLine().getStatusCode(), is(equalTo(200)));
//assertThat(httpResponse.getEntity().getContent(), is(equalTo(TeamMemberSingle200.EXPECTED_BODY_SINGLE_TEAM_MEMBER)) );
}
I'm getting below error on running mvn install
ConsumerTests The following methods annotated with #Pact were not executed during the test: ConsumerTests.singleTeamMemberSuccess If these are currently a work in progress, and a #Disabled annotation to the method
[ERROR] ConsumerTests.singleTeamMemberSuccess:42 ยป NoClassDefFound Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
Please can someone take a look and advise if I'm missing anything important to run the test successfully.
Thanks,
Poonam

Testng assert with DataProvider object values

i create a function test false login test but i want to assert with those loop test
here is my sample data
#DataProvider(name = "Lgindataprovides")
public Object[][] getData(){
Object[][] data= {
{"abcd#mail.com","12345666"}#email and password wrong (asset text = enter email is not available please register)
{"xyz#mail.com","12345666"},#email correct password wrong (assert text = password is wrong)
return data;
}
here is my test
#Test(dataProvider = "Lgindataprovides", dependsOnMethods = "boofoo")
public void logintest(String email, String passowrd) {
driver.get("https://dummyurl/login");
driver.findElement(By.id("email")).sendKeys(email);
driver.findElement(By.id("password")).sendKeys(passowrd);
driver.findElement(By.cssSelector("button[type='submit']"));
Assert.assertEquals(get1stdatatest, "enter email is not available please register")
Assert.assertEquals(get2nderrordatatest, "password is wrong")
}
buts it fails this test case how can I handle this?
what I want is
when this data"abcd#mail.com","12345666" is passed to the login test its should assert with this "enter email is not available please register"
when this dataxyz#mail.com","12345666 is passed to the login test its should assert with this "enter email is not available please register"
I see, you wand to check a unique error message per test data pair.
Add the 3rd item to data-provider with the error message text you expecting. So, each email/password will be linked with the error message.
#DataProvider(name = "Lgindataprovides")
public Object[][] getData(){
Object[][] data= {
{"abcd#mail.com","12345666", "error-message-1"},
{"xyz#mail.com","12345666", "error-message-2"}
}
return data;
}
Add 3rd arg to your test and assert that actual error matches the expected.
#Test(dataProvider = "Lgindataprovides", dependsOnMethods = "boofoo")
public void logintest(String email, String passowrd, String expectedError) {
driver.get("https://dummyurl/login");
driver.findElement(By.id("email")).sendKeys(email);
driver.findElement(By.id("password")).sendKeys(passowrd);
driver.findElement(By.cssSelector("button[type='submit']"));
Assert.assertEquals(getActualErrorMessage(driver), expectedError)
}
Adjust the method which getting the actual error message text. Your locator for driver.findElement sould find both password or email error messages. You might try to use xpath and search by some class //*[contains(#class, 'some-error-class']. So, you'll get any error message text on the form and it should work.
private String getActualErrorMessage(WebDriver driver) {
driver.findElement(By.xpath("...")).getText();
}
You might also do it inline without creating a new method. Also add some waits/timeouts if you need.

Bean Validation with JAX-RS (rest-easy): parameter name not recognized

I'm using JAX-RS resources with Bean Validation and integration between these two works as expected.
However, the default error messages generated in case of a validation error report parameter names as arg0, like so
[PARAMETER]
[login.arg0.password]
[password is required]
[]
Corresponding method definition:
#POST //and other JAX-RS annotations
public Response login(
#NotNull
#Valid
LoginBody loginBody) {
[...]
protected static class LoginBody {
#NotNull(message = EMAIL_REQUIRED)
public String email;
#NotNull(message = PASSWORD_REQUIRED)
public String password;
}
While I'm generally fine with this message pattern, what actually is annyoing, is the fact that the original parameter name is not recognized, i. e. I'd rather like to see
login.loginBody.password instead of arg0.
Is there an easy way to fix this, e. g. somehow provide an explicit name for that parameter?
I'm using WildFly Swarm 2017.6.0. From what I found out this means I have resteasy + resteasy-validator + hibernate-validator
Thanks.
You could try to compile your app with -parameters or instruct your IDE to do so, e.g. in case of
eclipse: preferences -> java -> compiler -> "store information about method parameters (usable via reflection)"
With that in place you then need to instruct the Bean Validation infrastructure (e.g. ) hibernate-validator to
use the ReflectiveParameterNamer via META-INF/validation.xml.
<parameter-name-provider>org.hibernate.validator.parameternameprovider.ReflectionParameterNameProvider</parameter-name-provider>
See also Hibernate Validator Configuration
I got something reliably working with the Paranamer library
META-INF/validation.xml:
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://jboss.org/xml/ns/javax/validation/configuration
validation-configuration-1.1.xsd"
version="1.1">
<default-provider>org.hibernate.validator.HibernateValidator
</default-provider>
<message-interpolator>org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator
</message-interpolator>
<traversable-resolver>org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver
</traversable-resolver>
<constraint-validator-factory>org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl
</constraint-validator-factory>
<parameter-name-provider>org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider</parameter-name-provider>
</validation-config>
To get paranamer working with wildfly I needed to create a parameter-namer jboss-module
and reference that module from the module.xml of the hibernate-validator module.
With that in place I could simply write:
#POST
public Response login(#NotNull #Valid #Named("authRequest") AuthRequest authRequest) {
return Response.ok().build();
}
...
public class AuthRequest {
#NotNull(message = AuthMessages.EMAIL_REQUIRED)
public String email;
#NotNull(message = AuthMessages.PASSWORD_REQUIRED)
public String password;
}
which yields the following response for a request sent via curl:
curl -H "Content-Type: application/json" -H "Accept: application/json" -d '{"email":"foo#bar.com"}' -v http://localhost:8080/javaweb-training/resources/auth
Response:
{"exception":null,"fieldViolations":[],"propertyViolations":[],"classViolations":[],"parameterViolations":[{"constraintType":"PARAMETER","path":"login.authRequest.password","message":"password.required","value":""}],"returnValueViolations":[]}%
... note login.authRequest.password instead of just login.arg0.password
There is a very simple solution: you can set your own error message in the constraint definition as follows
#NotNull(message = "password is required")
If you want a more generic solution based on the JAX-RS parameter annotations you can implement your own simple ParameterNamProvider and register it in validation.xml as follows. This has the advantage of not having to change the jboss module structure. I also didn't have to change any compiler flags...
public class AnnotatedParameterNameProvider implements ParameterNameProvider {
#Override
public List<String> getParameterNames(Constructor<?> constructor) {
return lookupParameterNames(constructor.getParameterAnnotations());
}
#Override
public List<String> getParameterNames(Method method) {
return lookupParameterNames(method.getParameterAnnotations());
}
private List<String> lookupParameterNames(Annotation[][] annotations) {
final List<String> names = new ArrayList<>();
if (annotations != null) {
for (Annotation[] annotation : annotations) {
String annotationValue = null;
for (Annotation ann : annotation) {
annotationValue = getAnnotationValue(ann);
if (annotationValue != null) {
break;
}
}
// if no matching annotation, must be the request body
if (annotationValue == null) {
annotationValue = "requestBody";
}
names.add(annotationValue);
}
}
return names;
}
private static String getAnnotationValue(Annotation annotation) {
if (annotation instanceof HeaderParam) {
return ((HeaderParam) annotation).value();
} else if (annotation instanceof PathParam) {
return ((PathParam) annotation).value();
} else if (annotation instanceof QueryParam) {
return ((QueryParam) annotation).value();
}
return null;
}
}
In validation.xml:
<validation-config xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.1.xsd"
version="1.1">
<parameter-name-provider>com.yourcompany.providers.AnnotatedParameterNameProvider</parameter-name-provider>
</validation-config>
Note that you can also customize how the error message is formatted by implementing your own MessageInterpolator and registering it in the validation.xml
Can you try to implement an exception mapper for ConstraintViolationExceptions and see if the information you have there (the list of constraint violations) can help you to obtain the parameter name?
Updated version of #thomas-darimont for Hibernate Validator 6.X.
Variant#1 - with build in Java 8 (using -parameters compile parameter)
Specify dependencies (gradle example):
// Define explicit hibernate validator 6.x
implementation('org.hibernate.validator:hibernate-validator:6.0.13.Final')
implementation('org.jboss.resteasy:resteasy-validator-provider-11:3.6.2.Final') {
// Exclude transitive hibernate validator 5.x
exclude group: 'org.hibernate', module: 'hibernate-validator'
}
Specify validator(s):
#GET
#Path("user/{userId}")
public Response getUser(#Size(min = 2) #PathParam("userId") String userId) {
return null;
}
Note: org.hibernate.validator.internal.engine.DefaultParameterNameProvider will return parameter names obtained from the Java reflection API.
Variant #2 - use ParaNamer library. (xml configuration)
In case you don't want to be dependant on compilation flag.
Specify dependencies (gradle example):
// Define explicit hibernate validator 6.x
implementation('org.hibernate.validator:hibernate-validator:6.0.13.Final')
implementation('org.jboss.resteasy:resteasy-validator-provider-11:3.6.2.Final') {
// Exclude transitive hibernate validator 5.x
exclude group: 'org.hibernate', module: 'hibernate-validator'
}
// ParaNamer library
implementation('com.thoughtworks.paranamer:paranamer:2.8')
Specify validator(s):
#GET
#Path("user/{userId}")
public Response getUser(#Size(min = 2) #PathParam("userId") String userId) {
return null;
}
Put <project_dir>/src/main/resources/META-INF/validation.xml
<?xml version="1.0" encoding="UTF-8"?>
<validation-config
xmlns="http://xmlns.jcp.org/xml/ns/validation/configuration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/validation/configuration
http://xmlns.jcp.org/xml/ns/validation/configuration/validation-configuration-2.0.xsd"
version="2.0">
<parameter-name-provider>org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider</parameter-name-provider>
</validation-config>
Note: Since Hibernate Validator 6.x org.hibernate.validator.parameternameprovider.ReflectionParameterNameProvider is deprecated, use org.hibernate.validator.parameternameprovider.ParanamerParameterNameProvider instead.
Question: Can I configure this with Java-code style only?
Unfortunately, no. (See details here).

The underlying connection was closed error while using .Include on EF objects

Following line of code gives me an error saying "The underlying connection was closed".
return this.repository.GetQuery<Countries>().Include(g => g.Cities).AsEnumerable().ToList();
But if I remove .Include(g => g.cities) it works fine.
this code is written in one of the operation in my WCF service, and I try to test it using WCF test client. I tried by calling this operation from MVC application also, and the same issue was occurring there too.
Also, i am using generic repository with entity framework
Repository code (only few important extract)
Constructor:
public GenericRepository(DbContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
this._dbContext = objectContext;
this._dbContext.Configuration.LazyLoadingEnabled = false;
this._dbContext.Configuration.ProxyCreationEnabled = false;
}
GetQuery method:
public IQueryable<TEntity> GetQuery<TEntity>() where TEntity : class
{
var entityName = GetEntityName<TEntity>();
return ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
}
Attempt#1
Created following overloads in repository code:
public IQueryable<TEntity> GetQuery<TEntity>(params string[] includes) where TEntity : class
{
var entityName = GetEntityName<TEntity>();
IQueryable<TEntity> query = ((IObjectContextAdapter)DbContext).ObjectContext.CreateQuery<TEntity>(entityName);
foreach(string include in includes)
{
query = query.Include(include);
}
return query;
}
public IQueryable<TEntity> GetQuery<TEntity>(Expression<Func<TEntity, bool>> predicate, params string[] includes) where TEntity : class
{
return GetQuery<TEntity>(includes).Where(predicate);
}
WCF is now trying to execute following line of code:
return this.repository.GetQuery<Countries>("Cities").AsEnumerable().ToList()
But it still gives the same error of "The underlying connection was closed". I tested it in WCF test client. However, when I debug the repository code it shows the navigation object getting included in result, but the issue seems occurring while trying to pass the output to client (WCF test client, or any other client)
After looking at the code you've now posted, I can conclude that, indeed, your DbContext is being closed at the end of the GetQuery method, and is thus failing when you try to use include. What you might want to do to solve it is to have an optional params variable for the GetQuery method that will take in some properties to be included, and just do the include right in the GetQuery method itself.

NHibernate: Could not create the driver from Test.SqlServerCeDriver_ImageFix

Im trying to resolve an issue where when using NHibernate with a SqlServerCeDriver that uses an image column you receive an error: "Byte array truncation to a length of 8000.". I found the following solution:
http://mgeorge-notes.blogspot.com/2009/05/nhibernate-mapping-from-binary-to.html
And created the following class:
namespace Test
{
public class SqlServerCeDriver_ImageFix : SqlServerCeDriver
{
protected override void InitializeParameter(IDbDataParameter dbParam, string name, SqlType sqlType)
{
base.InitializeParameter(dbParam, name, sqlType);
if (sqlType is BinarySqlType)
{
PropertyInfo dbParamSqlDbTypeProperty = dbParam.GetType().GetProperty("SqlDbType");
dbParamSqlDbTypeProperty.SetValue(dbParam, SqlDbType.Image, null);
}
}
}
}
But when I change the NHibernate mapping from
NHibernate.Driver.SqlServerCeDriver
to
Test.SqlServerCeDriver_ImageFix
I get the error, but I am not sure why.
The inner exception is: "Could not load type Test.SqlServerCeDriver. Possible cause: no assembly name specified."
Anyone have any ideas as to what im doing wrong?
When defining the driver in the config, define it with the AssemblyQualifiedName, i.e.:
Test.SqlServerCeDriver_ImageFix, MyAssemblyThatContainsThisType