Search code examples
postgresqlpgtap

Using pgTAP, can i select values/records into variables to use in the test?


I have a test factory function that creates and returns single records:

CREATE FUNCTION build_rec_for_test()
RETURNS mytable
AS $$
   INSERT INTO mytable VALUES (rand_uuid(),rand_int(),rand_int()) RETURNING *;
$$ LANGUAGE sql;

Is there a way to easily use that return value in pgTAP?

I'm basically looking to treat the return value as a variable, but maybe I'm too locked in the "regular" procedural style of thought.

A DO block is not useful - it does not write to stdout (link).

I'd like to do something like

BEGIN;
SELECT plan(1);

DECLARE my_rec = build_rec_for_test();

-- perform a test with values from the factory function
SELECT is(SELECT id FROM mytable, my_rec.id); 

SELECT * FROM finish();
ROLLBACK;

A more complete example might be something like

BEGIN;
SELECT plan(1);

DECLARE author = create_mock_author();
DECLARE post1 = create_mock_post_for(author);
DECLARE post2 = create_mock_post_for(author);
DECLARE comment1 = create_mock_comment_for(post1);
DECLARE comment2 = create_mock_comment_for(post2);

-- perform a test with values from the factory function
SELECT is(
    SELECT status FROM comments WHERE id = comment1.id, 
    'IN_REVIEW'
); 

-- I realize this is not a good test, because create_mock_post_for
-- will set the value, but it's an example of using an intermediate
-- record as part of the test
SELECT is(
    SELECT author_id FROM posts WHERE id = post1.id,
    author.id
);

SELECT * FROM finish();
ROLLBACK;

But obviously, that's not valid syntax.

Is there a way to accomplish this?


Solution

  • This appears to work nicely:

    BEGIN;
    SELECT plan(2);
    
    CREATE FUNCTION test_schema.test1()
    RETURNS SETOF TEXT
    AS $$
    DECLARE
      parent1 parent_type;
      parent2 parent_type;
      child1 child_type;
      child2 child_type;
    BEGIN
    
      SELECT * INTO parent1 FROM create_mock_parent();
      SELECT * INTO parent2 FROM create_mock_parent();
      SELECT * INTO child1 FROM create_mock_child(parent_id := parent1.id);
      SELECT * INTO child2 FROM create_mock_child(parent_id := parent2.id);
    
      RETURN QUERY SELECT is(parent1.id, child1.parent_id);
      RETURN QUERY SELECT is(parent2.id, child2.parent_id);
    
    END;
    $$ LANGUAGE plpgsql;
    
    SELECT * FROM test_schema.test1();
    
    SELECT * FROM finish();
    ROLLBACK;