Unit testing 单元测试NHibernate用户类型

Unit testing 单元测试NHibernate用户类型,unit-testing,nhibernate,usertype,Unit Testing,Nhibernate,Usertype,有没有人有很好的方法来单元测试他们的用户类型 举例来说,我的模型中有一个名为DateRange的对象,它有一个DatePoint开始和DatePoint结束。除了使范围类型操作可用于两个日期时间之外,这些对象还允许我调整手头任务的精度(例如,天、小时、分钟等)。当为我正在处理的应用程序存储到db时,我只需要将开始和结束存储为DateTime,不允许为空。如果没有用户类型,我想不出如何映射它,因此我有: /// <summary>User type to deal with <s

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

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

/// <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;
    }
}
///处理时间表跟踪持久性的用户类型。
公共类时间周期类型:IUserType
{
公共SqlType[]SqlTypes{
得到{
var types=新的SqlType[2];
类型[0]=新的SqlType(DbType.DateTime);
types[1]=新的SqlType(DbType.DateTime);
返回类型;
}
}
公共类型返回类型
{
获取{return typeof(DateRange);}
}
///归来
公共新布尔等于(对象x、对象y)
{
返回x!=null&&x.Equals(y);
}
///归来
公共int GetHashCode(对象x)
{
返回x.GetHashCode();
}
公共对象NullSafeGet(IDataReader rs,字符串[]名称,对象所有者)
{
var start=(DateTime)NHibernateUtil.DateTime.NullSafeGet(rs,name[0]);
var end=(DateTime)NHibernateUtil.DateTime.NullSafeGet(rs,names[1]);
返回新的日期范围(开始、结束、时间片分钟);
}
public void NullSafeSet(IDbCommand cmd,对象值,int索引){
检查。要求完整(值);
检查.RequireArgType(值);
var dateRange=((dateRange)值);
NHibernateUtil.DateTime.NullSafeSet(cmd,dateRange.Start,index);
NHibernateUtil.DateTime.NullSafeSet(cmd,dateRange.End,index);
}
公共对象深度复制(对象值){
检查。要求完整(值);
检查.RequireArgType(值);
var dateRange=((dateRange)值);
返回新的日期范围(DateRange.Start、DateRange.End);
}
公共布尔可换
{
获取{return false;}
}
公共对象替换(对象原始、对象目标、对象所有者){
//因为它是不可变的,所以我们可以按原样返回它
归还原件;
}
公共对象集合(对象缓存,对象所有者){
//用于缓存,因为它是不可变的,所以我们可以按原样返回它
返回缓存;
}
公共对象(对象值){
//用于缓存,因为它是不可变的,所以我们可以按原样返回它
返回值;
}
}
}

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

干杯,
Berryl

我想我可以在这里模拟/伪造一些依赖项,但最终决定最好的方法是使用数据库

一路上我学到了一些东西:

1) 在学习NHibernate技术时,拥有一套专门的工具是值得的,包括快速配置db和测试夹具的方法(实际上,其他一切都需要同样的敏捷工具)和一个专门的测试实验室,而你没有情感投入

2) mock不适合于您不拥有的接口,比如IDataReader


干杯

我为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 ) }; } } } 公共类ColorUserType:IUserType { 公共对象集合(对象缓存,对象所有者) { 返回缓存; } 公共对象深度复制(对象值) { 返回值; } 公共对象(对象值) { 返回值; } 公共新布尔等于(对象x、对象y) { if(ReferenceEquals(x,y)) { 返回true; } 如果(x==null | | y==null) { 返回false; } 返回x等于(y); } 公共int GetHashCode(对象x) { 返回x==null?typeof(Color).GetHashCode()+473:x.GetHashCode(); } 公共布尔可换 { 得到 { 返回true; } } 公共对象NullSafeGet(IDataReader rs,字符串[]名称,对象所有者) { var obj=NHibernateUtil.String.NullSafeGet(rs,names[0]); if(obj==null) { 返回null; } 返回ColorTranslator.FromHtml((字符串)obj); } public void NullSafeSet(IDbCommand cmd,对象值,int索引) { 如果(值==null) { ((IDataParameter)cmd.Parameters[index]).Value=DBNull.Value; } 其他的 { ((IDataParameter)cmd.Parameters[index]).Value=ColorTranslator.ToHtml((Color)Value); } } 公共对象替换(对象原始、对象目标、对象所有者) { 归还原件; } 公共类型返回类型 { 得到 { 返回类型(颜色); } } 公共SqlType[]SqlTypes { 得到 { 返回new[]{newsqltype(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] ); } } [测试类] 公共类ColorUserTypeTests { 公共TestContext TestContext{get;set;} [测试方法] 公共void AssembleTest() { var color=color.Azure; var userType=new ColorUserType(); var val=userType.assembly(颜色,null); 断言.AreEqual(颜色,val); } [测试方法] 公共无效DeepCopyTest() { var color=color.Azure; var userType=new ColorUserType(); var val=userType.DeepCopy(颜色); 断言.AreEqual(颜色,val); } [测试方法] 公开无效解除合同