2009-06-25 42 views
6

有没有人有单位测试他们的用户类型的好方法?作为示例,我的模型中有一个名为DateRange的对象,它具有DatePoint开始和DatePoint结束。除了为两个日期时间提供范围类型操作外,这些对象还可让我调整当前任务的精度(即日,小时,分钟等)。当存储到我正在处理的应用程序的数据库时,我只需要将开始和结束存储为DateTime,不允许有空值。我想不出如何映射这个没有用户等级和积分,所以我有:单元测试NHibernate的用户类型

/// <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; 
    } 
} 

}

现在我正在寻找一种方式来证明它的作品。提前致谢!

干杯, Berryl

回答

8

我创建了一个用户类型的System.Drawing.Color,这里是我单元如何与MSTest的和Moq测试它。

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]); 
     } 
    } 
0

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

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

1)这是值得有一个专门的工具集,包括一种能快速为其配置一个DB和测试夹具(同种学习NHibernate的技术时的努力您真的需要其他所有敏捷工具)以及您没有情绪投资的专用测试实验室。

2)嘲笑不适合您自己的界面,如IDataReader 。

干杯