测试视图中允许用户定义的数据类型?

user defined data types allowed in testing views?

我正在使用 tsqlt 测试一个视图 -- OrderHeader,它将 OrderHeader 与 OrderState 结合起来。在设置过程中,我为这两个 table 创建了伪造的 table,并插入了行。 table defs 和用户定义的数据类型如下。

当我 运行 我编写的 tsqt 过程来测试视图时,我创建了一个预期的 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' 

基本 table 是使用用户定义的类型定义的,如下所示:

UDT如下:

[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)

视图定义为:

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]

--

tsql 测试失败(它应该通过),并显示以下消息: (1 行受影响) [v_ctOrderHeader].[测试数据] 失败:(失败)Unexpected/missing 列

一个示例 'missing' 列是 |< countOrderNumber,使用 system_type_id AND user_type_id 作为 VARCHAR(50) 实际的 countOrderNumber 是 system_type_id = VARCHAR(50) 和 user_type_id = dbo.orderNumber.

我已经尝试了所有排列来创建预期的 table(使用或不使用 UDT)并且总是得到相同的错误。
我还尝试将视图的结果插入到临时 table 中:

SELECT * INTO #t 来自 v_ctOrderHeader

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

并得到相同的错误(不匹配)。

您是否尝试通过 [=23= 创建 实际和预期的 table ] ..进入?

这将创建具有完全相同格式的两个 table 并删除列差异。使用 TOP(0) 以获得预期的 table。一个示例测试是:

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)

我无法重现您遇到的问题,并且能够 运行 您提供的测试没有错误,即它按预期通过了。

供参考,我是运行ning SQL2017和tSQLt 1.0.5873.27393。

这是我的代码(为方便起见全部放在一个块中):

--!
--! Create base objects
--!
CREATE TYPE [dbo].[orderNumber] FROM varchar(50) ;
CREATE TYPE [dbo].[id]          FROM int ;
CREATE TYPE [dbo].[orderType]   FROM nvarchar(50) ;
CREATE TYPE [dbo].[orderClass]  FROM nvarchar(50) ;
CREATE TYPE [dbo].[orderState]  FROM nvarchar(50) ;
CREATE TYPE [dbo].[site]        FROM varchar(50) ;
CREATE TYPE [dbo].[region]      FROM varchar(50) ;
CREATE TYPE [dbo].[description] FROM nvarchar(500) ;
CREATE TYPE [dbo].[orderMethod] FROM nvarchar(50) ;
CREATE TYPE [dbo].[displayName] FROM nvarchar(128) ;
GO

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]
GO
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]
GO

IF OBJECTPROPERTYEX(OBJECT_ID(N'[dbo].[v_ctOrderHeader]'), N'IsView') = 1
    DROP VIEW [dbo].[v_ctOrderHeader]
GO
CREATE OR ALTER VIEW [dbo].[v_ctOrderHeader]
AS
    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
GO

--!
--! Create test objects
--!
EXEC tSQLt.NewTestClass @ClassName = N'WhosebugTests';
GO

IF OBJECTPROPERTYEX(OBJECT_ID(N'[WhosebugTests].[SetUp]'), N'IsProcedure') = 1
    DROP PROCEDURE [WhosebugTests].[SetUp]
GO
CREATE PROCEDURE [WhosebugTests].[SetUp]
AS
BEGIN
    EXEC tSQLt.FakeTable @TableName = N'dbo.ctOrderState' ;
    EXEC tSQLt.FakeTable @TableName = N'dbo.ctOrderHeader' ;

    INSERT dbo.ctOrderState (orderState, [description] , displayName, availableForCounting)
    VALUES (10, 'Not Specified 10', 'Number 10', 1 )
        ,  (100, 'Not Specified 100', 'Number 100', 1 )
        ,  (200, 'Not Specified 200', 'Number 200', 1 )
    ;

    INSERT dbo.ctOrderHeader
    (
      countOrderNumber
    , orderId
    , orderType
    , orderClass
    , orderState
    , site
    , region
    , instance
    , prOrderId
    , description
    , isSoftCount
    , dtDue
    , orderMethod
    )
    VALUES
    (
      '10'                 -- countOrderNumber - orderNumber
    , 10                   -- orderId - id
    , '10'                 -- orderType - orderType
    , '10'                 -- orderClass - orderClass
    , '10'                 -- orderState - orderState
    , '10'                 -- site - site
    , '10'                 -- region - region
    , 10                   -- instance - int
    , 10                   -- prOrderId - id
    , '10'                 -- description - description
    , 1                -- isSoftCount - bit
    , '20200101' -- dtDue - datetimeoffset(7)
    , '10'                 -- orderMethod - orderMethod
    )
    , (
      '100'                -- countOrderNumber - orderNumber
    , 100                  -- orderId - id
    , '100'                -- orderType - orderType
    , '100'                -- orderClass - orderClass
    , '100'                -- orderState - orderState
    , '100'                -- site - site
    , '100'                -- region - region
    , 100                  -- instance - int
    , 100                  -- prOrderId - id
    , '100'                -- description - description
    , 1                -- isSoftCount - bit
    , '20200102' -- dtDue - datetimeoffset(7)
    , '100'                -- orderMethod - orderMethod
    )
    , (
      '200'                -- countOrderNumber - orderNumber
    , 200                  -- orderId - id
    , '200'                -- orderType - orderType
    , '200'                -- orderClass - orderClass
    , '200'                -- orderState - orderState
    , '200'                -- site - site
    , '200'                -- region - region
    , 200                  -- instance - int
    , 200                  -- prOrderId - id
    , '200'                -- description - description
    , 0                -- isSoftCount - bit
    , '20200103' -- dtDue - datetimeoffset(7)
    , '200'                -- orderMethod - orderMethod
    )
    ;

END
GO

IF OBJECTPROPERTYEX(OBJECT_ID(N'[WhosebugTests].[test v_ctOrderHeader join conditione]'), N'IsProcedure') = 1
    DROP PROCEDURE [WhosebugTests].[test v_ctOrderHeader join condition]
GO
CREATE OR ALTER PROCEDURE [WhosebugTests].[test v_ctOrderHeader join condition]
AS
BEGIN
    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'
               ,'20200101'
               ,'10'
               ,'1')
              ,('100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'100'
               ,'1'
               ,'20200102'
               ,'100'
               ,'1')
              ,('200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'200'
               ,'0'
               ,'20200103'
               ,'200'
               ,'1');

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

--!
--! Run the tests
--!
EXEC tSQLt.Run 'WhosebugTests';
GO

这是我得到的结果:

+----------------------+
|Test Execution Summary|
+----------------------+

|No|Test Case Name                                            |Dur(ms)|Result |
+--+----------------------------------------------------------+-------+-------+
|1 |[WhosebugTests].[test v_ctOrderHeader join condition]|     47|Success|
-----------------------------------------------------------------------------
Test Case Summary: 1 test case(s) executed, 1 succeeded, 0 failed, 0 errored.
-----------------------------------------------------------------------------

您的测试或设置是否与我在上面所做的有所不同?也许是旧版本的 tSQLt?

希望对您有所帮助