Search code examples
tsqlt

user defined data types allowed in testing views?


I'm using tsqlt to test a view -- OrderHeader, which joins OrderHeader with OrderState. In a set up procedure I create fake tables for those two tables, and insert rows. The table defs and user defined data types are below.

When I run the tsqt procedure I've written to test the views, I create an expected table

CREATE TABLE expected_v_ctOrderHeader
        (
        [countOrderNumber] dbo.orderNumber NOT NULL
        ,[orderId] dbo.id NOT NULL
        ,[orderType] dbo.orderType NOT NULL
        ,[orderClass] dbo.orderClass NOT NULL
        ,[orderState] dbo.orderState NOT NULL
        ,[site] dbo.site NOT NULL
        ,[region] [dbo].[region] NULL
        ,[currentInstance] INT NOT NULL
        ,[prOrderId] [dbo].[id] NULL 
        ,[description] dbo.description NULL
        ,[isSoftCount] BIT NOT NULL
        ,[dtDue] DATETIMEOFFSET NULL
        ,[orderMethod]  [dbo].[orderMethod] NOT NULL
        ,[availableForCounting] BIT NOT NULL
        );

Insert into it the same data as in the SetUp procedure:

    INSERT INTO dbo.expected_v_ctOrderHeader
        (
         [countOrderNumber]
        ,[orderId]
        ,[orderType]
        ,[orderClass]
        ,[orderState]
        ,[site]
        ,[region]
        ,[currentInstance]
        ,[prOrderId]
        ,[description]
        ,[isSoftCount]
        ,[dtDue]
        ,[orderMethod]
        ,[availableForCounting]
        )
    VALUES
           ('10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'10'
           ,'1'
           ,'1/1/2020'
           ,'10'
           ,'1')
          ,('100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'100'
           ,'1'
           ,'2/1/2020'
           ,'100'
           ,'0')
          ,('200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'200'
           ,'0'
           ,'3/1/2020'
           ,'200'
           ,'1')

Do an EXEC tsqlt.AssertEqualsTable


    EXEC tSQLt.AssertEqualsTable
        @Expected = N'dbo.expected_v_ctOrderHeader' 
      , @Actual = N'dbo.v_ctOrderHeader' 

The base tables are defined using user defined types as follows:

The UDTs are as follows:

[dbo].[orderNumber] VARCHAR(50)
[dbo].[id]          INT
[dbo].[orderType]   NVARCHAR(50)
[dbo].[orderClass]  NVARCHAR(50)
[dbo].[orderState]  NVARCHAR(50)
[dbo].[site]        VARCHAR(50)
[dbo].[region]      VARCHAR(50)
[dbo].[description] NVARCHAR(500)
[dbo].[orderMethod] NVARCHAR(50)

The view definition is:

SELECT ch.[countOrderNumber]    --[dbo].[orderNumber]
      ,ch.[orderId]             --[dbo].[id] 
      ,ch.[orderType]           --[dbo].[orderType]
      ,ch.[orderClass]          --[dbo].[orderClass]
      ,ch.[orderState]          --[dbo].[orderState]
      ,ch.[site]                --[dbo].[site] 
      ,ch.[region]              --[dbo].[region]
      ,ch.[instance] AS currentInstance  --INT
      ,ch.[prOrderId]           --[dbo].[id] 
      ,ch.[description]         --[dbo].[description]
      ,ch.[isSoftCount]         --BIT
      ,ch.[dtDue]               --DATETIMEOFFSET
      ,ch.[orderMethod]         --[dbo].[orderMethod]
      ,cs.[availableForCounting]--BIT
  FROM [dbo].[ctOrderHeader] ch
  INNER JOIN [dbo].[ctOrderState] cs ON ch.orderState = cs.orderState

--tsql

CREATE TABLE [dbo].[ctOrderHeader](
    [countOrderNumber] [dbo].[orderNumber] NOT NULL,
    [orderId] [dbo].[id] NOT NULL,
    [orderType] [dbo].[orderType] NOT NULL,
    [orderClass] [dbo].[orderClass] NOT NULL,
    [orderState] [dbo].[orderState] NOT NULL,
    [site] [dbo].[site] NOT NULL,
    [region] [dbo].[region] NULL,
    [instance] [int] NOT NULL,
    [prOrderId] [dbo].[id] NULL,
    [description] [dbo].[description] NULL,
    [isSoftCount] [bit] NOT NULL,
    [dtDue] [datetimeoffset](7) NULL,
    [orderMethod] [dbo].[orderMethod] NOT NULL,
 CONSTRAINT [PK_ctOrderHeader_countOrderNumber] PRIMARY KEY CLUSTERED 
(
    [countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [UQ_ctOrderHeader_countOrderNumber] UNIQUE NONCLUSTERED 
(
    [countOrderNumber] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

CREATE TABLE [dbo].[ctOrderState](
    [orderState] [dbo].[orderState] NOT NULL,
    [description] [dbo].[description] NOT NULL,
    [displayName] [dbo].[displayName] NOT NULL,
    [availableForCounting] [bit] NOT NULL,
 CONSTRAINT [PK_ctOrderState_orderState] PRIMARY KEY CLUSTERED 
(
    [orderState] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

--

The tsql test fails (it should pass), with the following message: (1 row affected) [v_ctOrderHeader].[Test Data] failed: (Failure) Unexpected/missing column(s)

One example 'missing' column is |< countOrderNumber, with a system_type_id AND user_type_id as VARCHAR(50) The actual countOrderNumber is system_type_id = VARCHAR(50) and user_type_id = dbo.orderNumber.

I have tried all permutations for creating the expected table (using the UDT, or not) and always get the same error.
I have also tried inserting into a temp table the results of the view:

SELECT * INTO #t FROM v_ctOrderHeader

EXEC tSQLt.AssertEqualsTable
    @Expected = N'dbo.expected_v_ctOrderHeader' -- nvarchar(max)
  , @Actual = #t   

And get the identical errors (mismatches).


Solution

  • Have you tried creating both the actual and expected tables via SELECT .. INTO?

    This will create both tables with exactly the same format and remove the column difference. Use TOP(0) for the expected table. An example test is:

    CREATE OR ALTER PROC v_ctOrderHeader.[Test Data]
    AS
    
    --arrange
    SELECT TOP (0)
           *
    INTO v_ctOrderHeader.Expected
    FROM dbo.YourViewName;
    
    --populate v_ctOrderHeader.Expected
    
    EXEC tSQLt.FakeTable @TableName = N'dbo.ctOrderHeader';
    EXEC tSQLt.FakeTable @TableName = N'dbo.ctOrderState';
    
    --populate dbo.ctOrderHeader
    --populate dbo.ctOrderState
    
    --act
    SELECT *
    INTO v_ctOrderHeader.Actual
    FROM dbo.YourViewName;
    
    --assert
    EXEC tSQLt.AssertEqualsTable @Expected = N'v_ctOrderHeader.Expected', -- nvarchar(max)
                                 @Actual = N'v_ctOrderHeader.Actual',     -- nvarchar(max)
                                 @Message = N'',                          -- nvarchar(max)
                                 @FailMsg = N'';                          -- nvarchar(max)