In some of our apps, we use Cassandra in our “unit tests”, similar in style to how a Rails or Django app does unit testing. We originally tried to avoid requiring Cassandra for unit testing, but we found that we spent a lot of time reimplementing a poorman’s “fake cassandra” in memory, which was 1) not going to help us catch any query errors and 2) easily 30% of the code for a pull request. With those things in mind, we decided to just require Cassandra during unit testing.
Anyone that’s had to write tests that involve dates or times understands the pain here, and packages like freezegun make it a lot easier to have deterministic tests. For anyone coming from the ruby world, freezegun is similar to timecop. However, when we started using freezegun in our unit tests, we would see a cryptic error like the following:
SyntaxException: <ErrorMessage code=2000 [Syntax error in CQL query] message="line 3:64 missing EOF at '-01'">
We registered Freezegun’s FakeDateTime with our session encoder, so what’s the problem?
It turns out that for some reason the encoder doesn’t include quotes when it performs the interpolation of a FakeDateTime. This query works just fine with a regular datetime or arrow object.
select * from users where registered_at = %(registration_date)s
To get it to work with a FakeDateTime, simple add quotes:
select * from users where registered_at = '%(registration_date)s'
Bonus: CQLSH and timezone support
We save all our datetimes in UTC, but when running queries locally with cqlsh, the times will get transformed into local time. This can be annoying and confusing. Fortunately, running cqlsh with the env var TZ=UTC will fix that. Newer versions of cqlsh have configurable timezone support.
$> TZ=UTC cqlsh