How to write properly a groovy unit test with jUnit? - unit-testing

I am getting started with Groovy and I don't know how to write unit tests over my methods written on a class. For example:
One my methods on sample.groovy :
class sample {
def length = { list -> list.size() }
...
}
So, I have one class named sampleTest.groovy :
class sampleTest extends GroovyTestCase {
#Test
public void testLength() {
def result = length([2, 3, 8, 9, 0, 1, 5, 7])
assert result == 8
}
}
BTW, when I run this test, an error throws to me:
groovy.lang.MissingMethodException: No signature of method: sampleTest.length() is applicable for argument types: (java.util.ArrayList) values: [[2, 3, 8, 9, 0, 1, 5, 7]]
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:133)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:141)
...

length is a (non-static) property of the sample class. Because it's non-static, you need to evaluate it against a sample instance, e.g.
class sampleTest extends GroovyTestCase {
#Test
public void testLength() {
def result = new sample().length([2, 3, 8, 9, 0, 1, 5, 7])
assertEquals 8, result
}
}
Also, you should try to use the assertion methods provided by GroovyTestCase such as assertEquals, assertNotNull, assertTrue, rather than the assert keyword.
You should also capitalize your class names, e.g. Sample and SampleTest rather than sample and sampleTest.

Related

Iterate List of Object in Kotlin TestCase

I'm using Unit Test using Kotlin and unable to iterate List of Objects in my Test Case, Kindly check my below Coding,
#Test
#WithMockOAuth(siteId = "5698965", subPermissions = [SubPermission.GETD])
fun `get fee zero`() {
val body = """
{
"newMessage": {
"call": true,
"callMessatgeCount": 3,
"discounted": 2,
"NewFees": 4.99,
"Id" : "extra SIM Business"
}
}
""".trimIndent()
this.server.expect(requestTo("${integrationClientProperties.url}/main/0767777777/register/"))
.andRespond(withSuccess(body, MediaType.APPLICATION_JSON_UTF8))
assertThat(service.getValues("0767777777"))
.hasSize(3)
.first()
.hasFieldOrPropertyWithValue("callMessatgeCount", 3)
.hasFieldOrPropertyWithValue("NewFees", BigDecimal.ZERO)
this.server.verify()
}
Above i can able to check hasFieldOrPropertyWithValue for the first() element, As hasSize(3) i need to check all the 3 values which is List of Objects in the same TestCase method.
List of objects as Below
ListValue:[
{
"newMessage": {
"call": true,
"callMessatgeCount": 3,
"discounted": 2,
"NewFees": 4.99,
"Id" : "extra SIM Business"
},
{
"newMessage": {
"call": true,
"callMessatgeCount": 3,
"discounted": 2,
"NewFees": 0,
"Id" : "extra SIM Business"
},
{
"newMessage": {
"call": true,
"callMessatgeCount": 3,
"discounted": 2,
"NewFees": 4.99,
"Id" : "extra SIM Business"
}
]
Note: I tried element(index) to check the list of objects using multiple test cases.
Updated
Library" org.assertj.core.api.Assertions and supports java8
Assuming you are using AssertJ from the method names and that you have a Java-8-supporting version (i.e. 3.5+), you can find the allSatisfy method:
Verifies that all the elements satisfy given requirements expressed as a Consumer.
This is useful to perform a group of assertions on elements.
From the docs, something like the following should work
assertThat(service.getValues("0767777777"))
.hasSize(3)
.allMatch { assertThat(it)
.hasFieldOrPropertyWithValue("callMessatgeCount", 3)
.hasFieldOrPropertyWithValue("NewFees", BigDecimal.ZERO)
}
You could look into Kotlin-specific libraries as well (especially if you need to compile to JVM 6).

Add optional message parameter to assertEquals

Disclaimer: I'm totally new to Haxe, but I have experience in many other languages.
I have tests similar to the following:
function doTest(type:SomethingMagic, tests:Array<Array<Int>>) {
for (t in tests) {
var res = DoSomeMagicalWork(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
assertEquals(type, res.type);
}
}
The problem with this is that the unit test framework, when run on many different arrays, doesn't give me the correct line for which the test failed. In other words, if I'm running this method with a bunch of arrays, like:
doTest(SOME_MAGIC_TYPE,
[[0, 0, 0, 1625, 0, 35, 0, 0, 0, 0, 0],
...
]);
and one of these lines fails, it doesn't tell me which line failed. Now, I know that I could probably restructure these tests to be a bit more intuitive anyway, but this was written by someone else, and I don't have the ability to change each of these at the moment.
What I'd like to do is the following:
function doTest(type:SomethingMagic, tests:Array<Array<Int>>) {
var number = 0;
for (t in tests) {
var res = DoSomeMagicalWork(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7]);
assertEquals(type, res.type, "Test #" + number + " for type " + type);
number++;
}
}
So, basically, I'd like to be able to pass in some extra messaging information to the assertEquals function, similar to what one can do in other unit testing frameworks. Then, upon failure, it would output the standard assertion message, possibly appended by the additional message I sent as a parameter to the function. Originally, I thought it was as simple as sub-classing haxe.TestCase, but that doesn't appear to be quite as simple as I thought, due to the way Haxe interprets types (apparently).
Has anyone had success with something similar to this that could give me a recommendation on how to accomplish it?
If you want to only get the position of the error you can use haxe.PosInfos as the last argument of your doTest() function and pass that arguemnt to assertEquals() like this:
import haxe.unit.TestCase;
class Main {
static function main() {
var r = new haxe.unit.TestRunner();
r.add(new Test());
r.run();
}
}
class Test extends TestCase {
public function new() {
super();
}
public function testExample() {
doTest(1, 1);
doTest(1, 2);
doTest(3, 3);
}
function doTest(a:Int, b:Int, ?pos:haxe.PosInfos) {
assertEquals(a, b, pos);
}
}
Online example here
It will give you the position that called doTest() in the error:
Test::testExample() ERR: Main.hx:18(Test.testExample) - expected '1' but was '2'
Another option if you want to add a custom message is to catch the assertEquals() error and rethrow the currentTest with a custom error like this:
import haxe.unit.TestCase;
class Main {
static function main() {
var r = new haxe.unit.TestRunner();
r.add(new Test());
r.run();
}
}
class Test extends TestCase {
public function new() {
super();
}
public function testExample() {
doTest(1, 1, "Error on test 1");
doTest(1, 2, "Error on test 2");
doTest(3, 3, "Error on test 3");
}
function doTest(a:Int, b:Int, errorMsg:String, ?pos:haxe.PosInfos) {
try {
assertEquals(a, b, pos);
} catch(e:Dynamic) {
currentTest.error = errorMsg;
throw currentTest;
}
}
}
Online example here
Which will give you the following error:
Test::testExample() ERR: Main.hx:18(Test.testExample) - Error on test 2
You are effectively blending multiple tests into a single one. And Haxe cannot tell where your array element is defined (line number, etc)
What I suggest is to change the signature of doTest to accept Array<Int> instead of Array<Array<Int>> and call doTest multiple times instead of just once. Together with the suggestion from Justo, passing the pos object to assetEquals, you will get the position correctly.

grails 2.5 - how to put a list in config.groovy

Is there any way to put a list in the config.groovy file? e.g:
environments {
development {
account {
defaultList = [1, 3, 5]
}
trying to read this in a service, e.g:
def grailsApplication
:
def accountTypesToCreate = grailsApplication.config.account.defaultList
results in
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'groovy.util.ConfigObject#66c2331a' with class 'groovy.util.ConfigObject' to class 'java.util.List' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.util.List(groovy.util.ConfigObject)
Also tried getProperty
try this:
def accountTypesToCreate = grailsApplication.config.account.defaultList as List

sbt doesn't recognize ScalaTest Table-driven property checks as tests

I wrote some ScalaTest Table-driven property checks and I'm trying to run them with sbt test. Looking at the report I see that ScalaTest can recognize all the JUnit tests I have (they are in the same class as the checks), it runs property checks (i.e., forAll body), but it doesn't treat forAll as a test. If it fails I see the stack trace in the report (with ScalaTest failed test exception) and sbt says there was an "error" during the test run, but it says that all of the tests passed. The total number of tests in the report includes only JUnit tests.
Is there the support for this style of tests in sbt?
forAll in PropertyChecks is not a test. It is essentially a glorified assertion. You need to place assertions inside named tests. How to do that depends on your chosen style. For example, in FunSuite, you'd write something like:
class MySpec extends FunSuite with PropertyChecks {
test("give the test a name here") {
forAll(x: Int, y: Int) {
// make assertions here
}
}
}
Instead of calling forAll, make the test class extend from org.scalatest.prop.Checkers and then in each test, call check with the Property to be tested. In this case, "Property" probably means the forAll that you've created.
So I'm going to guess that currently you have a test class that looks like:
class ExampleSuite extends AssertionsForJUnit {
val fractions = Table(
("n", "d"),
( 1, 2),
///...
)
forAll (fractions) { (n: Int, d: Int) => // ...
#Test def verifySomethingElse = ???
}
I believe what you need to do is extend from Checkers and move your forAll into a test.
class ExampleSuite extends AssertionsForJUnit with org.scalatest.prop.Checkers {
#Test def verifyFractions = {
val fractions = Table(
("n", "d"),
( 1, 2),
///...
)
check(forAll (fractions) { (n: Int, d: Int) => ???)
}
#Test def verifySomethingElse = ???
}
The standard way is to create a FunSuite test with Matchers and TableDrivenPropertyCheck
Example:
import org.scalatest._
import org.scalatest.prop.TableDrivenPropertyChecks._
class CreateSpec extends FunSuite with Matchers {
test("B-Tree-Create for different degree parameter value") {
val params = Table(("degree", "result"),
(0, Tree(Leaf(), 0)),
(2, Tree(Leaf(), 1)),
(1999, Tree(Leaf(), 1999)))
forAll(params) {(degree, result) => Algorithms.create(degree) == result}
}
}

Can Googletest value-parameterized with multiple, different types of parameters match mbUnit flexibility?

I'd like to write C++ Google tests which can use value-parameterized tests with multiple parameters of different data types, ideally matching the complexity of the following mbUnit tests written in C++/CLI.
For an explanation of mbUnit, see the Hanselman 2006 article. As of this 2019 edit, the other links he includes are dead.
Note how compact this is, with the [Test] attribute indicating this is a test method and the [Row(...)] attributes defining the values for an instantiation.
[Test]
[Row("Empty.mdb", "select count(*) from collar", 0)]
[Row("SomeCollars.mdb", "select count(*) from collar", 17)]
[Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)]
void CountViaDirectSQLCommand(String^ dbname, String^ command, int numRecs)
{
String^ dbFilePath = testDBFullPath(dbname);
{
StAnsi fpath(dbFilePath);
StGdbConnection db( fpath );
db->Connect(fpath);
int result = db->ExecuteSQLReturningScalar(StAnsi(command));
Assert::AreEqual(numRecs, result);
}
}
Or even better, this more exotic testing from C# (pushing the boundaries of what can be defined in .Net attributes beyond what's possible in C++/CLI):
[Test]
[Row("SomeCollars.mdb", "update collar set x=0.003 where hole_id='WD004'", "WD004",
new string[] { "x", "y" },
new double[] { 0.003, 7362.082 })] // y value unchanged
[Row("SomeCollars.mdb", "update collar set x=1724.8, y=6000 where hole_id='WD004'", "WD004",
new string[] { "x", "y" },
new double[] { 1724.8, 6000.0 })]
public void UpdateSingleRowByKey(string dbname, string command, string idValue, string[] fields, double[] values)
{
...
}
The help says Value-parameterized tests will let you write your test only once and then easily instantiate and run it with an arbitrary number of parameter values. but I'm fairly certain that is referring to the number of test cases.
Even without varying the data types, it seems to me that a parameterized test can only take one parameter?
2019 update
Added because I got pinged about this question. The Row attribute shown is part of mbUnit.
For an explanation of mbUnit, see the Hanselman 2006 article. As of this 2019 edit, the other links he includes are dead.
In the C# world, NUnit added parameterised testing in a more powerful and flexible way including a way to handle generics as Parameterised Fixtures.
The following test will be executed fifteen times, three times for each value of x, each combined with 5 random doubles from -1.0 to +1.0.
[Test]
public void MyTest(
[Values(1, 2, 3)] int x,
[Random(-1.0, 1.0, 5)] double d)
{
...
}
The following test fixture would be instantiated by NUnit three times, passing in each set of arguments to the appropriate constructor. Note that there are three different constructors, matching the data types provided as arguments.
[TestFixture("hello", "hello", "goodbye")]
[TestFixture("zip", "zip")]
[TestFixture(42, 42, 99)]
public class ParameterizedTestFixture
{
private string eq1;
private string eq2;
private string neq;
public ParameterizedTestFixture(string eq1, string eq2, string neq)
{
this.eq1 = eq1;
this.eq2 = eq2;
this.neq = neq;
}
public ParameterizedTestFixture(string eq1, string eq2)
: this(eq1, eq2, null) { }
public ParameterizedTestFixture(int eq1, int eq2, int neq)
{
this.eq1 = eq1.ToString();
this.eq2 = eq2.ToString();
this.neq = neq.ToString();
}
[Test]
public void TestEquality()
{
Assert.AreEqual(eq1, eq2);
if (eq1 != null && eq2 != null)
Assert.AreEqual(eq1.GetHashCode(), eq2.GetHashCode());
}
[Test]
public void TestInequality()
{
Assert.AreNotEqual(eq1, neq);
if (eq1 != null && neq != null)
Assert.AreNotEqual(eq1.GetHashCode(), neq.GetHashCode());
}
}
Yes, there's a single parameter. You can make that parameter be arbitrarily complex, though. You could adapting the code from the documentation to use you Row type, for example:
class AndyTest : public ::testing::TestWithParam<Row> {
// You can implement all the usual fixture class members here.
// To access the test parameter, call GetParam() from class
// TestWithParam<T>.
};
Then define your parameterized test:
TEST_P(AndyTest, CountViaDirectSQLCommand)
{
// Call GetParam() here to get the Row values
Row const& p = GetParam();
std::string dbFilePath = testDBFullPath(p.dbname);
{
StAnsi fpath(dbFilePath);
StGdbConnection db(p.fpath);
db.Connect(p.fpath);
int result = db.ExecuteSQLReturningScalar(StAnsi(p.command));
EXPECT_EQ(p.numRecs, result);
}
}
Finally, instantiate it:
INSTANTIATE_TEST_CASE_P(InstantiationName, AndyTest, ::testing::Values(
Row("Empty.mdb", "select count(*) from collar", 0),
Row("SomeCollars.mdb", "select count(*) from collar", 17),
Row("SomeCollars.mdb", "select count(*) from collar where max_depth=100", 4)
));
An alternative to using a custom structure as the parameter is to use the parameter generator ::testing::Combine(g1, g2, ..., gn). This generator allows you to combine the other parameter generators into a set of parameters with a type std::tuple that has a template type that matches the types of the values provided.
Note that this generator produces the Cartesian product of the values provided. That means that every possible ordered tuple will be created. I believe the original question is asking for a strict array of parameters with the provided values, which this does not support. If you need to have an array of strict parameters, you could use a tuple with the parameter generator ::testing::Values(v1, v2, ..., vN) where each value is a separate tuple.
Example:
#include <string>
#include <tuple>
class MyTestSuite :
public testing::TestWithParam<std::tuple<std::string, std::string, int>>
{
};
TEST_P(MyTestSuite, TestThatThing)
{
functionUnderTest(std::get<0>(GetParam()),
std::get<1>(GetParam()),
std::get<2>(GetParam()));
. . .
}
INSTANTIATE_TEST_SUITE_P(
MyTestGroup,
MyTestSuite,
::testing::Combine(
::testing::Values("FirstString1", "FirstString2"),
::testing::Values("SecondString1", "SecondString2"),
::testing::Range(10, 13)));
INSTANTIATE_TEST_SUITE_P(
MyOtherTestGroupThatUsesStrictParameters,
MyTestSuite,
::testing::Values(
{"FirstString1", "SecondString1", 10},
{"FirstString2", "SecondString2", 32},
{"FirstString3", "SecondString3", 75}));
In the above example, the parameters created for MyTestGroup would look like the following:
[
{"FirstString1", "SecondString1", 10},
{"FirstString1", "SecondString1", 11},
{"FirstString1", "SecondString1", 12},
{"FirstString1", "SecondString2", 10},
{"FirstString1", "SecondString2", 11},
{"FirstString1", "SecondString2", 12},
{"FirstString2", "SecondString1", 10},
{"FirstString2", "SecondString1", 11},
{"FirstString2", "SecondString1", 12},
{"FirstString2", "SecondString2", 10},
{"FirstString2", "SecondString2", 11},
{"FirstString2", "SecondString2", 12}
]
Refer to the GoogleTest documentation for further details. (Accessed on 12/17/2019)