有没有人有一个好的方法来单元测试他们的用户类型?

举例来说,我的模型中有一个名为 DateRange 的对象,它具有 DatePoint 开始和 DatePoint 结束。除了使范围类型操作可用于两个日期时间之外,这些对象还允许我调整手头任务的精度(即日、小时、分钟等)。当存储到我正在开发的应用程序的数据库中时,我只需要将开始和结束存储为 DateTime,不允许为空。我想不出如何在没有 UserType 的情况下映射它,所以我有:

/// <summary>User type to deal with <see cref="DateRange"/> persistence for time sheet tracking.</summary>
public class TimePeriodType : IUserType
{

    public SqlType[] SqlTypes {
        get {
            var types = new SqlType[2];
            types[0] = new SqlType(DbType.DateTime);
            types[1] = new SqlType(DbType.DateTime);
            return types;  

        }
    }

    public Type ReturnedType
    {
        get { return typeof(DateRange); }
    }

    /// <summary>Just return <see cref="DateRange.Equals(object)"/></summary>
    public new bool Equals(object x, object y)
    {
        return x != null && x.Equals(y);
    }

    /// <summary>Just return <see cref="DateRange.GetHashCode"/></summary>
    public int GetHashCode(object x)
    {
        return x.GetHashCode();
    }

    public object NullSafeGet(IDataReader rs, string[] names, object owner)
    {
        var start = (DateTime)NHibernateUtil.DateTime.NullSafeGet(rs, names[0]);
        var end = (DateTime)NHibernateUtil.DateTime.NullSafeGet(rs, names[1]);

        return new DateRange(start, end, TimeSlice.Minute);
    }

    public void NullSafeSet(IDbCommand cmd, object value, int index) {
        Check.RequireNotNull<DateRange>(value);
        Check.RequireArgType<DateRange>(value);
        var dateRange = ((DateRange)value);

        NHibernateUtil.DateTime.NullSafeSet(cmd, dateRange.Start, index);
        NHibernateUtil.DateTime.NullSafeSet(cmd, dateRange.End, index);
    }

    public object DeepCopy(object value) {
        Check.RequireNotNull<DateRange>(value);
        Check.RequireArgType<DateRange>(value);
        var dateRange = ((DateRange) value);

        return new DateRange(dateRange.Start, dateRange.End);
    }

    public bool IsMutable
    {
        get { return false; }
    }

    public object Replace(object original, object target, object owner) {
        //because it is immutable so we can just return it as is  
        return original;
    }

    public object Assemble(object cached, object owner) {
        //Used for caching, as it is immutable we can just return it as is  
        return cached;
    }

    public object Disassemble(object value) {
        //Used for caching, as it is immutable we can just return it as is  
        return value;
    }
}

}

现在我正在寻找一种方法来证明它有效。提前致谢!

欢呼,贝里尔

有帮助吗?

解决方案

我为 System.Drawing.Color 创建了一个用户类型,以下是我如何使用 MSTest 和 起订量.

ColorUserType.cs:

public class ColorUserType : IUserType
{
    public object Assemble( object cached, object owner )
    {
        return cached;
    }

    public object DeepCopy( object value )
    {
        return value;
    }

    public object Disassemble( object value )
    {
        return value;
    }

    public new bool Equals( object x, object y )
    {
        if(ReferenceEquals(x, y ) )
        {
            return true;
        }
        if( x == null || y == null )
        {
            return false;
        }
        return x.Equals( y );
    }

    public int GetHashCode( object x )
    {
        return x == null ? typeof( Color ).GetHashCode() + 473 : x.GetHashCode();
    }

    public bool IsMutable
    {
        get 
        {
            return true;
        }
    }

    public object NullSafeGet( IDataReader rs, string[] names, object owner )
    {
        var obj = NHibernateUtil.String.NullSafeGet( rs, names[0] );
        if( obj == null )
        {
            return null;
        }
        return ColorTranslator.FromHtml( (string)obj );
    }

    public void NullSafeSet( IDbCommand cmd, object value, int index )
    {
        if( value == null )
        {
            ( (IDataParameter)cmd.Parameters[index] ).Value = DBNull.Value;
        }
        else
        {
            ( (IDataParameter)cmd.Parameters[index] ).Value = ColorTranslator.ToHtml( (Color)value );
        }
    }

    public object Replace( object original, object target, object owner )
    {
        return original;
    }

    public Type ReturnedType
    {
        get
        {
            return typeof( Color );
        }
    }

    public SqlType[] SqlTypes
    {
        get
        {
            return new[] { new SqlType( DbType.StringFixedLength ) };
        }
    }
}

ColorUserTypeTests.cs

    [TestClass]
    public class ColorUserTypeTests
    {
        public TestContext TestContext { get; set; }

        [TestMethod]
        public void AssembleTest()
        {
            var color = Color.Azure;
            var userType = new ColorUserType();
            var val = userType.Assemble( color, null );
            Assert.AreEqual( color, val );
        }

        [TestMethod]
        public void DeepCopyTest()
        {
            var color = Color.Azure;
            var userType = new ColorUserType();
            var val = userType.DeepCopy( color );
            Assert.AreEqual( color, val );
        }

        [TestMethod]
        public void DissasembleTest()
        {
            var color = Color.Azure;
            var userType = new ColorUserType();
            var val = userType.Disassemble( color );
            Assert.AreEqual( color, val );
        }

        [TestMethod]
        public void EqualsTest()
        {
            var color1 = Color.Azure;
            var color2 = Color.Bisque;
            var color3 = Color.Azure;
            var userType = new ColorUserType();

            var obj1 = (object)color1;
            var obj2 = obj1;

            Assert.IsFalse( userType.Equals( color1, color2 ) );
            Assert.IsTrue( userType.Equals( color1, color1 ) );
            Assert.IsTrue( userType.Equals( color1, color3 ) );
            Assert.IsFalse( userType.Equals( color1, null ) );
            Assert.IsFalse( userType.Equals( null, color1 ) );
            Assert.IsTrue( userType.Equals( null, null ) );
            Assert.IsTrue( userType.Equals( obj1, obj2 ) );
        }

        [TestMethod]
        public void GetHashCodeTest()
        {
            var color = Color.Azure;
            var userType = new ColorUserType();

            Assert.AreEqual( color.GetHashCode(), userType.GetHashCode( color ) );
            Assert.AreEqual( typeof( Color ).GetHashCode() + 473, userType.GetHashCode( null ) );
        }

        [TestMethod]
        public void IsMutableTest()
        {
            var userType = new ColorUserType();
            Assert.IsTrue( userType.IsMutable );
        }

        [TestMethod]
        public void NullSafeGetTest()
        {
            var dataReaderMock = new Mock();
            dataReaderMock.Setup( m => m.GetOrdinal( "white" ) ).Returns( 0 );
            dataReaderMock.Setup( m => m.IsDBNull( 0 ) ).Returns( false );
            dataReaderMock.Setup( m => m[0] ).Returns( "#ffffff" );

            var userType = new ColorUserType();
            var val = (Color)userType.NullSafeGet( dataReaderMock.Object, new[] { "white" }, null );

            Assert.AreEqual( "ffffffff", val.Name, "The wrong color was returned." );

            dataReaderMock.Setup( m => m.IsDBNull( It.IsAny() ) ).Returns( true );
            Assert.IsNull( userType.NullSafeGet( dataReaderMock.Object, new[] { "black" }, null ), "The color was not null." );

            dataReaderMock.VerifyAll();
        }

        [TestMethod]
        public void NullSafeSetTest()
        {
            const string color = "#ffffff";
            const int index = 0;

            var mockFactory = new MockFactory( MockBehavior.Default );

            var parameterMock = mockFactory.Create();
            parameterMock.SetupProperty( p => p.Value, string.Empty );

            var parameterCollectionMock = mockFactory.Create();
            parameterCollectionMock.Setup( m => m[0] ).Returns( parameterMock.Object );

            var commandMock = mockFactory.Create();
            commandMock.Setup( m => m.Parameters ).Returns( parameterCollectionMock.Object );

            var userType = new ColorUserType();

            userType.NullSafeSet( commandMock.Object, ColorTranslator.FromHtml( color ), index );
            Assert.AreEqual( 0, string.Compare( (string)( (IDataParameter)commandMock.Object.Parameters[0] ).Value, color, true ) );

            userType.NullSafeSet( commandMock.Object, null, index );
            Assert.AreEqual( DBNull.Value, ( (IDataParameter)commandMock.Object.Parameters[0] ).Value );

            mockFactory.VerifyAll();
        }

        [TestMethod]
        public void ReplaceTest()
        {
            var color = Color.Azure;
            var userType = new ColorUserType();
            Assert.AreEqual( color, userType.Replace( color, null, null ) );
        }

        [TestMethod]
        public void ReturnedTypeTest()
        {
            var userType = new ColorUserType();
            Assert.AreEqual( typeof( Color ), userType.ReturnedType );
        }

        [TestMethod]
        public void SqlTypesTest()
        {
            var userType = new ColorUserType();
            Assert.AreEqual( 1, userType.SqlTypes.Length );
            Assert.AreEqual( new SqlType( DbType.StringFixedLength ), userType.SqlTypes[0] );
        }
    }

其他提示

我想我可以嘲笑/伪造一些依赖关系在这里,但清盘决定做,这是通过使用数据库的最佳方式。

有些事情,我一路上了解到:

1),它的价值在学习NHibernate的技术有一个专门的工具集,包括一种能快速为其配置一个DB和测试夹具(同种灵活的工具,你所需要的一切努力,真的)和一个专用的测试实验室,你不必英寸的情感投资

2)嘲笑不适合自己到接口你不拥有,像IDataReader的。

干杯

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top