Question

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.

Was it helpful?

Solution

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

OTHER TIPS

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.

The workaround I've used is to change the production code to use a view, which then uses the synonym. I can then mock the view using tSQLt.FakeTable.

I have also faced similar issue. I have 2 databases i.e. config and main db I have a table 'tableA' in config db. and its synonym is created in main db with same name i.e. dbo.tableA. But while mocking that synonym it gave me same error. So here is my solution which worked for me.

First, I have created synonym of a tSQLt.FakeTable sp from config db into my main db for e.g.

CREATE SYNONYM tSQLt.tSqltFakeTable_config FOR [Config_db].tSQLt.faketable

Now in test case, I used new synonym tSQLt.tSqltFakeTable_config as below to fake a synonym of 'tableA'

CREATE PROC [testclass].[test faking synonym which points to another db] 
AS
BEGIN
    --arrange
    exec [tSQLt].tSqltFakeTable_config 'dbo.tableA';

    --act

    --assert

END

But I felt there would be only 1 issue that if you uninstall tSQLt from config db. You have to keep track of all such new synonyms and remove them first then you can uninstall tSQLt from Config db. Suggestions are welcome.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top