Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tSQLt fails when attempting to FakeTable a synonym table

Tags:

sql

tsql

tsqlt

I am using tSQLt (through Red Gate's SQL Test version 1.0.0.455). tSQLt is installed on database A. I am trying to do a tSQLt.FakeTable on a table in database B on the same SQL server instance through a synonym on database A.

Code:

ALTER PROCEDURE [ErrorType109NonTankHasSizeOrVolume].[test AliasTest] AS

BEGIN
Exec tSQLt.FakeTable 'dbo.Bygning';

Insert Into dbo.Bygning (ObjStatus) Values (1);

EXEC tSQLt.AssertEquals 1, 1
END;

Where dbo.Bygning is a synonym in database A referring to a table in database B and ObjStatus is a column in dbo.Bygning

Error message:

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.

[ErrorType109NonTankHasSizeOrVolume].[test AliasTest] failed: An invalid parameter or option was specified for procedure 'sp_addextendedproperty'.{sp_addextendedproperty,37}

Is there any way to tSQLt.FakeTable synonym tables?

Clarification: The error message comes when running the test.

like image 469
steenhulthin Avatar asked Feb 21 '23 17:02

steenhulthin


2 Answers

tSQLt does not support faking on synonyms at the moment. However, I think it may be easy to add support for this. I quickly prototyped the following fix and hope it may solve your issue. Can you please try it and confirm? If it works out for you, I'll make sure it gets into the next release.

ALTER PROCEDURE tSQLt.Private_MarkFakeTable
  @SchemaName NVARCHAR(MAX),
  @TableName NVARCHAR(MAX),
  @NewNameOfOriginalTable NVARCHAR(4000)
AS
BEGIN
   DECLARE @UnquotedSchemaName NVARCHAR(MAX);SET @UnquotedSchemaName = OBJECT_SCHEMA_NAME(OBJECT_ID(@SchemaName+'.'+@TableName));
   DECLARE @UnquotedTableName NVARCHAR(MAX);SET @UnquotedTableName = OBJECT_NAME(OBJECT_ID(@SchemaName+'.'+@TableName));
   DECLARE @Level1Type NVARCHAR(MAX);

   SELECT @Level1Type = 
     CASE type
       WHEN 'SN' THEN 'SYNONYM'
       ELSE 'TABLE'
     END
   FROM sys.objects
   WHERE object_id = OBJECT_ID(@SchemaName+'.'+@TableName);


   EXEC sys.sp_addextendedproperty 
      @name = N'tSQLt.FakeTable_OrgTableName', 
      @value = @NewNameOfOriginalTable, 
      @level0type = N'SCHEMA', @level0name = @UnquotedSchemaName, 
      @level1type = N'TABLE',  @level1name = @UnquotedTableName;
END;
GO
like image 53
dennislloydjr Avatar answered Mar 02 '23 11:03

dennislloydjr


I ran into this today and devised the following solution.

In the Assemble section:

CREATE TABLE #mock
(
    id_item VARCHAR(15),
    descr_1 VARCHAR(50)
)
INSERT INTO #mock
  ( id_item, descr_1 )
VALUES ('123456-01', 'Great description here'),
       ('123456-02', 'Blue, gnarly, cloud')
EXEC sp_rename 'syn_name', 'syn_name_orig'
CREATE SYNONYM syn_name FOR #mock

Then clean up at the end of the act section:

DROP SYNONYM syn_name
EXEC sp_rename 'syn_name_orig', 'syn_name'

It's working for me. Might have side-effects for concurrent processes trying to use that synonym, but I only run my tests in a development environment, so I am not worried about it.

like image 28
Alexander Garden Avatar answered Mar 02 '23 13:03

Alexander Garden