More informative asserts in Scala - unit-testing

I'm looking for asserts in the style of Google's testing framework, where something like ASSERT_LT(a, b) will check that $a is less than $b, and if not, will print the values of $a and $b in the error message. The asserts I've found so far just stop execution without printing anything useful by default. Any pointers?
Bonus: I like to write assertion-heavy code (not just in the tests), so it would be nice if the assertions are quick to evaluate.
Context: I came across this when writing unittests using this code as a template.

Specs2 defines a number of matchers such as must be_<=. At first I thought these needed to integrated into a specification, but at the bottom of the matchers page it says that they are modular functionality that "you should be able to reuse in your own test
framework". As an example, "You can reuse [traits such as] org.specs2.matcher.MustMatchers to write anything like 1 must be_==(1) and
get a Result back".
ScalaTest has its own matchers, as well. For example, one must be < (7).

def assert_<[A <% Ordered[A]](a: => A, b: => A) {
assert(a < b, "Assertion failed: expected %s < %s" format (a, b))
}
scala> assert_<(2, 1)
java.lang.AssertionError: assertion failed: Assertion failed: expected 2 < 1

Related

chicken scheme srfi-64 test-error problems

I am using chicken scheme version 4.9.0.1 and am working on a
unit test suite using the unit test package srfi-64.
I am having trouble with test-error in this unit test package.
A minimal example of the problem:
(require-extension srfi-64)
(test-begin "error testing")
(define (exn-tester)
(error "What does srfi-64 want?"))
(test-error "the exn-tester" 'exn (exn-tester))
(test-end)
Results in the report:
%%%% Starting test error testing
Group begin: error testing
Test begin:
test-name: "the exn-tester"
Test end:
result-kind: fail
actual-error: #<condition: (exn)>
expected-error: exn
Group end: error testing
# of unexpected failures 1
The problem is clearly in my test-error because I don't know how
to represent the exception in a form that test-error understands.
I've tried multiple variations on the actual-error as listed,
but to no success.
Specifically, what should I code for the expected-error in the
test-error call?
The SRFI spec itself basically says "it's implementation-dependent", but after a look at the code it seems you can simply pass it a predicate:
(require-extension srfi-64)
(test-begin "error testing")
(define (exn-tester)
(error "What does srfi-64 want?"))
(test-error "the exn-tester" (condition-predicate 'exn) (exn-tester))
(test-end)
Please note that in the CHICKEN community, the test egg is the facto testing egg. However, it currently has no way to test for a specific exception type. I once wrote this macro for the Postgres egg's test suite:
(define-syntax test-error*
(syntax-rules ()
((_ ?msg (?error-type ...) ?expr)
(let-syntax ((expression:
(syntax-rules ()
((_ ?expr)
(condition-case (begin ?expr "<no error thrown>")
((?error-type ...) '(?error-type ...))
(exn () (##sys#slot exn 1)))))))
(test ?msg '(?error-type ...) (expression: ?expr))))
((_ ?msg ?error-type ?expr)
(test-error* ?msg (?error-type) ?expr))
((_ ?error-type ?expr)
(test-error* (sprintf "~S" '?expr) ?error-type ?expr))))
To be used as follows:
(test-error* "Result value error for out of bounds row"
(exn postgresql bounds)
(value-at (query conn "SELECT NULL") 0 1))
The (exn postgresql bounds) tells the test to accept a composite condition (refer to SRFI-12 for more info) of the types exn, postgresql and bounds. It can have other types, but in this example, these three must be present for the test to pass.
With your tips, the following works well enough:
(require-extension test)
test-begin "error-testing")
(define (exn-tester)
(error "What does srfi-64 want?"))
(test-error (exn-tester))
(test-end "error-testing")
Attempts to use your define-syntax resulted in "unbound variable: exn".
Perhaps I require additional extension to use this?
However, your define-syntax will warrant future attention. I am only getting started in Scheme and, having a test driven background, am most interested in my code being the very best.

How could you unit test against this bad Linq-To-SQL predicate?

Given the following example code:
Table<Person> tableToQuery = MethodThatGetsReferenceToPersonTable();
string searchType = "NonUser";
IQueryable<Person> queryResults = tableToQuery.Where(p =>
(p.IsMale == false) && // exclude male people
type.Equals("User", StringComparison.OrdinalIgnoreCase)
? p.User != null : p.User == null);
I am new to L2S, but do have some of experience with EntityFramework. I would not expect the above query to work correctly in an ORM like EF because of the type.Equals that gets invoked in the predicate's ternary expression. I would instead expect EF to throw an exception since it cannot convert that part of the predicate into a (SQL) store expression.
With L2S, it seems that the .Where is returning data, but it is not excluding items where p.Male == true when type == "NonUser. I have already fixed the code above to pull the type.Equals ternary out of the predicate and return correct results, and am now trying to write a test to assert the correct results. The problem I am running into is that the L2S code is actually behind an IRepository<Person> interface.
So the actual code looks more like this:
string searchType = "NonUser";
ICriteria<Person> query = new Query<Person>(p =>
(p.IsMale == false) && // exclude male people
type.Equals("User", StringComparison.OrdinalIgnoreCase)
? p.User != null : p.User == null);
IQueryable<Person> = _peopleRepository.FindByQuery(query)
...and the _peopleRepository implementation just passes the query.Predicate as an argument to the L2S Table<Person>.Where.
Questions:
Is it correct that the L2S Table<Person>.Where is not returning the correct results because of the ternary expression in the lambda predicate? I assume so since taking the ternary out an generating separate ICriteria<Person> objects depending on the value of searchType is yielding correct results. However I am not so certain if this is because L2S cannot convert the ternary into a store expression, or if it is caused by something else.
Since the method under test depends on a IRepository<Person> instance, how could I actually write a unit test around this? Mocking the IRepository<Person> in a unit test would not allow us to test the effects of the lambda on real underlying data. Creating a FakePersonRepository backed by some kind of IList<Person> would not reveal the actual defect either because the above lambda with the ternary expression returns expected results using linq-to-objects. Is there any way we could mock part of L2S so that we can possibly generate SQL using the lambda, and write assertions against that instead?
Is this just something we have to do with an integration test and an actual L2S context with connection string, and cannot properly unit test? My definition of "integration test" means "connect to an actual database running in a separate process from the test runner using some kind of connection string", whereas "unit test" means "do everything in the test runner process".
Is it correct that the L2S (...) is not returning the correct results
It does return correct results, but not the results you expect, because you read the query as a human being and not as a compiler. The latter reads this:
tableToQuery.Where(p =>
((p.IsMale == false) && type.Equals("User", StringComparison.OrdinalIgnoreCase))
? p.User != null
: p.User == null);
We humans tend to read this:
tableToQuery.Where(p => (p.IsMale == false) &&
(type.Equals("User", StringComparison.OrdinalIgnoreCase)
? p.User != null
: p.User == null));
2./3. how could I actually write a unit test around this?
Mocking and unit testing is virtually impossible. I stick to integration tests when I want to test the behavior of a data layer. For Entity Framework I collected some reasons for integration tests here. Much of it applies too LINQ-to-SQL as well.

Cannot run remote function inside Unit test

im trying to setup some unit tests with Elixir but running into this error below. What am I doing wrong?
cannot invoke remote function PropertyManager.Database.get/0 inside match
Here is my code:
property_manager_test.exs
defmodule PropertyManagerTest do
use ExUnit.Case
test "the truth" do
assert 1 + 1 == 2
end
test "get value from db" do
assert PropertyManager.Database.get() = "test this"
end
end
database.ex
defmodule PropertyManager.Database do
def get do
"test this"
end
end
Try with == instead of =
What you're doing in your code is a pattern match, which means it will try to match the right side to the pattern on the left side. A pattern can't contain function calls, which is probably the cause of your error.

Spock interaction based test does not fail

I have the following two Spock tests:
def "sends a valid response when no users exist"() {
setup:
def exchange = new HttpServerExchange(Mock(ServerConnection))
usersRepository.size() >> 0
when:
firstRunHandler.handleRequest(exchange)
then:
1*response.send(exchange, _)
}
def "does not send content when any users exist"() {
setup:
usersRepository.size() >> 1
when:
firstRunHandler.handleRequest(new HttpServerExchange(Mock(ServerConnection)))
then:
0*response.send(_, _)
}
The second one should definitely fail, since the interaction is stll there. But it always passes. I can not even make it fail with:
then:
assert false
0*response.send(_, _)
IntelliJ Idea still shows it as "green". But when I change the "then" to
then:
assert false
the test fails, so it is definitely being run and executed as a spock test.
I don't get much info from Spock, and I did not find out anything when debugging. What am I missing? What can I do to diagnose this problem?

Specs2 spec fails to compile after upgrade to latest version

I have just upgraded Specs2 on my project and now some specs won't compile and it isn't clear why they're not, here's the spec:
"fail validation if a connection is disconnected" in {
val connection = factory.create
awaitFuture(connection.disconnect)
factory.validate(connection) match {
case Failure(e) => ok("Connection successfully rejected")
case Success(c) => failure("should not have come here")
}
}
(The whole file can be seen here)
And the compiler says:
could not find implicit value for evidence parameter of type
org.specs2.execute.AsResult[Product with Serializable]
"fail validation if a connection is disconnected" in {
^
And while I understand what it is saying, it doesn't make any sense given I am returning ok or failure and I'm covering all cases on my match.
Any idea what could be wrong here?
The compiler is trying to find the common type of the 2 match branches. The first line is using ok which is a MatchResult and the second line is using failure which is returning a Result. Their only common type is Product with Serializable.
The fix is simply to use the opposite value of ok which is ko:
factory.validate(connection) match {
case Failure(e) => ok("Connection successfully rejected")
case Success(c) => ko("should not have come here")
}
You could also write
import org.specs2.execute._
...
factory.validate(connection) match {
case Failure(e) => Success("Connection successfully rejected")
case Success(c) => failure("should not have come here")
}
There is however no success(message: String) method available to match the corresponding failure. I will add it to the next specs2 version for better symmetry.