I've just discovered JUnit Rules.
I have a Groovy unit test case as follows...
class CheckRegistrationValidatorTest {
#Test
void 'input validation'() {
def checkRegistrationValidator =
new CheckRegistrationValidator(regexCarTruckRegNo:/^[a-zA-Z0-9]{1,6}$/, regexMotorcycleRegNo:/^[a-zA-Z0-9]{3,5}$/, regexTrailorRegNo:/^[a-zA-Z0-9]{6}$/, regexBoatRegNo:/^[a-zA-Z0-9]{1,6}$/, regexVin:/^(?=.*[0-9])(?=.*[a-zA-Z])([a-hj-npr-z0-9]{17})$/, regexChassis:/^[a-zA-Z0-9]{1,6}$/)
def input = [
vehicleClassCode: '0',
vehicleIdentificationType: 'registrationNumber',
vehicleRegistrationNumber: 'WEB001'
]
checkRegistrationValidator.validate input
}
}
I want to replace the checkRegistrationValidator instantiation with an #ClassRule. I've attempted to read up on them but I'm just not getting it.
Can someone help me with how to create a #ClassRule just to do that line of code.
thanks
Related
I am facing issue with Webclient and mockito
Below is my service code:
public Flux<Config> getConfigs(String param1, String param2) {
MultiValueMap<String, String> queryParams = new LinkedMultiValueMap<>();
if(!StringUtils.isEmpty(param2)) {
queryParams.add("name", param2);
}
String path = "api/v1/config";
return webClient.get().uri(uriBuilder -> uriBuilder.path(path)
.queryParams(queryParams)
.build())
.retrieve().bodyToFlux(Config.class)
.doOnError(MyRuntimeException::throwError);
}
Test Case i am trying is failing with below error:
Strict stubbing argument mismatch. Please check:
- this invocation of 'uri' method:
requestHeadersUriSpec.uri(
com.rs.para.conf.service.ConfigServiceImpl$$Lambda$309/1334433160#3925299f
);
Test case code:
#Test
public void testConfig() {
List<Config> configs = new ArrayList<>();
doReturn(requestHeadersUriMock).when(webClientMock).get();
doReturn(requestHeadersMock).when(requestHeadersUriMock)
.uri(anyString());
doReturn(responseMock).when(requestHeadersMock).retrieve();
doReturn(Flux.fromIterable(configs)).when(responseMock).bodyToFlux(Config.class);
Flux<Config> configFlux = configService.getConfigs("100005", "test");
}
I can run normal GET without query param but when I am trying to run this test which has query param it's giving me error
PS: I don't want to use mockwebserver
The problem here is you are using a lambda inside the uri method. Whereas in the test cases you are using anyString(). Also since URI has multiple ways of implementation, just using anyString() will not work. Providing a specific class is what is required.
Changing
doReturn(requestHeadersMock).when(requestHeadersUriMock)
.uri(anyString());
to
doReturn(requestHeadersMock).when(requestHeadersUriMock).uri(Mockito.any(Function.class));
does the job here.
i need to test 'tableInfo' method of Service class
Here is my junit test script:
class JUnitTest extends Specification {
Service service
Table table = GroovyMock(Table)
def spy = Spy(Service){
getTable() >> table
}
def setup() {
service = new Service(
table: table
)
}
def "when table contains information"() {
given:
spy.internalMethod(*_) >> [Bean.BEAN_SUCCESS]
table.getUnits(*_) >> {}
Response response = new Response()
when:
spy.tableInfo(.....)
then:
response.status == 0
response.error == []
}
Question: I am getting null pointer exception in table.getUnits as below
"java.lang.NullPointerException: Cannot invoke method getUnits() on
null object"
Please help me out of this
If you want to call the method every time. But need aware of exception means, simply check the condition before calling table.getUnits() method like below.
if(table.getUnits!=null)
table.getUnits();
I wanted to know if there's any way to add test suites dynamically in junit 4.
For example I have a TestClassA as mentioned below having test case "test1"
class TestClassA
{
#Test
public void test1()
{
createTestClassDynamically(); // this creates a test class having
// setUp(), tearDown() methods and one test case .
}
}
Test case test1 has a method createTestClassDynamically() that dynamically creates a new test class (lets say TestClassB) having setUp(), tearDown() methods and one test case (lets say test2()).
I want to run the test1 and then when TestClassB is dynamically generated I want test case "test2" also to be executed.
I know this is quite complicated and not the best thing to do but in my framework I need to do it to generate large number of test classes dynamically rather than having them physically in the package.
Can anyone please provide any help/suggestions?
I have solved this is my framework using the Parameterized feature of Junit 4 which helps to execute same test case with different parameters.
Below mentioned is the sample code on how I acheived it, thought to post it if it helps anyone.
Also, if someone has a better solution, feel free to post it.
class TestClassA
{
private TestClassB classBObj;
public TestClassA(TestClassB obj) {
classBObj= obj;
}
#Test
public void test1()
{
// createTestClassDynamically(); // remove this method as Parameterized
// feature will take care of dynamic test execution.
}
#Test
public void test2()
{
// Test case from Test class B using TestClassB object (classBObj)
}
public static Collection<Object[]> getParameters() {
Collection<Object[]> parameteres = new ArrayList<Object[]>();
Object[] obj1 = new Object[]{new TestClassB()};
Object[] obj2 = new Object[]{new TestClassB()};
parameteres.add(obj1);
parameteres.add(obj2);
// ....... add more test data this way or create a loop
return parameteres;
}
}
I'd like to be able to use JUnit 4.7's ExpectedException #Rule in Scala. However, it doesn't seem to catch anything:
import org.junit._
class ExceptionsHappen {
#Rule
def thrown = rules.ExpectedException.none
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
This still fails with a NumberFormatException.
To make this work with JUnit 4.11 in Scala, you should meta-annotate your annotation so that the annotation is applied only to the (synthetic) getter method, not the underlying field:
import org.junit._
import scala.annotation.meta.getter
class ExceptionsHappen {
#(Rule #getter)
var thrown = rules.ExpectedException.none
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
EDIT: Following the release of JUnit 4.11, you can now annotate a method with #Rule.
You will use it like:
private TemporaryFolder folder = new TemporaryFolder();
#Rule
public TemporaryFolder getFolder() {
return folder;
}
For earlier versions of JUnit, see the answer below.
--
No, you can't use this directly from Scala. The field needs to be public and non-static. From
org.junit.Rule:
public #interface Rule: Annotates fields that contain rules. Such a field must be public, not static, and a subtype of TestRule.
You cannot declare a public fields in Scala. All fields are private, and made accessible by accessors. See the answer to this question.
As well as this, there is already an enhancement request for junit (still Open):
Extend rules to support #Rule public MethodRule someRule() { return new SomeRule(); }
The other option is that it non-public fields be allowed, but this has already been rejected: Allow #Rule annotation on non-public fields.
So your options are:
clone junit, and implement the first suggestion, the method, and submit a pull request
Extend the Scala class from a java class which implements the #Rule
-
public class ExpectedExceptionTest {
#Rule
public ExpectedException thrown = ExpectedException.none();
}
and then inheriting from that:
class ExceptionsHappen extends ExpectedExceptionTest {
#Test
def badInt: Unit = {
thrown.expect(classOf[NumberFormatException])
Integer.parseInt("one")
}
}
which works correctly.
As a very newbie to Scala I am just using a very simple workaround: explicitly catch the exception and fail if your expected exception is not thrown.
Below is a sample skeleton:
try {
*your code that should throw an exception*
fail("Did not generate *the.Exception.you.expect*")
} catch {
case t: *the.Exception.you.expect* => // do nothing, it's expected :)
}
Without knowing JUnit rules, and without testing it, because I don't have an appropriate setup at hand, I go out on a limb and suggest turning thrown into a val.
I guess its some member that is initialized with something and then it gets some state and then some other machinery checks the state against something. You are always creating new ones and keep forgetting the expectation.
If Scala has something similar like static imports, then catch-exception is an alternative to JUnit 4.7's ExpectedException #Rule.
I'm still using JUnit 4, and found #Juh_'s comment instructive. This worked in Scala 2.11.0.
import org.junit.rules.ExpectedException
import org.junit.{Rule, Test}
import scala.reflect.{ClassTag, classTag}
class DeleteMe {
object Thrower {
def throwException[R <: Throwable: ClassTag](message: String): Unit = {
throw classTag[R].runtimeClass.getConstructor(classOf[String]).newInstance(message).asInstanceOf[R]
}
}
#Rule
def exceptionRule:ExpectedException = ExpectedException.none()
#Test(expected = classOf[Exception])
def checkConversionExceptions = {
val myMessage = "My Message"
exceptionRule.expectMessage(myMessage)
Thrower.throwException[Exception](myMessage)
()
}
}
All,
I am currently using JUnit 4 for writing test cases. I am fairly new to JUnit and finding it difficult to test my main class which takes arguments. I have specified the arguments to my JUnit test class by:
1 > Right click JUnit test class
2 > Goto Run As -> Run Configurations
3 > Select the Arguments tab and specify a value (I have entered an invalid argument i.e. the main class expects the command line argument to be converted to an int and I am passing a String value that cannot be converted to int)
However, the main class that I am testing, if the command line argument cannot be converted to a int, than I throw IllegalArgumentException. However, the JUnit does not show the testMain() method as Error or Failure. I don't think my setup is right for the JUnit class. Can anyone please guide me where I am going wrong
To test your class main method simply write something like:
#Test(expected = IllegalArgumentException.class)
public void testMainWithBadCommandLine()
{
YourClass.main(new String[] { "NaN" });
}
Change the main() method to something like this:
public static void main(String[] args)
{
MyClass myclass = new MyClass(args);
myclass.go();
}
Move the code that was in main() to the new method go(). Now, your test method can do this:
public void myClassTest()
{
String[] args = new String[]{"one", "two"}; //for example
MyClass classUnderTest = new MyClass(testArgs);
classUnderTest.go();
}
Firstly the arguments should be in the program arguments section. Normally the launching point of the application that's the main method doesn't need to be tested if you design the app to be testable.
Refactor the class
public static class ArgumentValidator
{
public static boolean nullOrEmpty(String [] args)
{
if(args == null || args.length == 0)
{
throw new IllegalArgumentException(msg);
}
//other methods like numeric validations
}
}
You can now easily test the nullOrEmpty method using junit like
#Test(expected = IllegalArgumentException.class)
public void testBadArgs()
{
ArgumentValidator.nullOrEmpty(null);
}
I think this is a better approach