I am trying to test a method that should return an error. I can’t figure out how to test it properly.
var result = Chunk.tryFrom(&allocator, &chunk_data);
defer result.deinit(&allocator);
try std.testing.expectError(ChunkError.ChunkCrcInvalid, result);
if i do this, the compiler complains that i call deinit on the error union. (same with errdefer)
if i remove the defer statement, compiler complains about memory leak.
That’s by design, since the function is returning an error union. The error unio doesn’t have a deinit() method defined on it, but the value it contains does.
You need to unwrap the error union first. You often do this via try <expr> or <expr1> catch <expr2>, but you want to do this conditionally here.
Notice how the if construct supports unwrapping error unions. The form for this is:
if (expr) |value| ... else |err| ...;
You can use this to do the deinit() only if there is a value there and do nothing in case an error was returned instead (or, if you want to assert more strongly that an error should be returned, the value branch can just be unreachable).