如果需要测试另一个项目中的非公共属性,则Microsoft单元测试向导会创建访问器对象。在我的单元测试中,我创建助手函数,这样我就不会在每个单元测试方法中重复相同的代码。目前,我有两个几乎相同的测试,除了一个采用标准公共对象,另一个采用访问器版本。因为访问器是基于公共对象的,所以我应该有一个函数。我曾假设我可以使用泛型通过简单的强制转换来完成。但在posting the question之后,我发现还有更多的工作要做,包括必须更新底层对象。我的问题是,另一种方法可以将这些冗余方法减少到只有一个函数使用强制转换(或另一个)方法?
下面是现有的两个函数:
// Common function to create a new test record with standard Account object
internal static void CreateAccount(out Account account, bool saveToDatabase)
{
DateTime created = DateTime.Now;
string createdBy = _testUserName;
account = new Account(created, createdBy);
account.Notes = Utilities.RandomString(1000);
if (saveToDatabase)
account.Create();
}
// Common function to create a new test record with Account_Accessor
internal static void CreateAccount(out Account_Accessor account, bool saveToDatabase)
{
DateTime created = DateTime.Now;
string createdBy = _testUserName;
account = new Account_Accessor(created, createdBy);
account.Notes = Utilities.RandomString(1000);
if (saveToDatabase)
account.Create();
}我有24个这样的单元测试,真实的对象平均有10个属性,我在这里简化了示例。
下面是Unit Test API创建的访问器代码(同样,为了简化示例,我对其进行了精简):
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.ObjectModel;
using System.Data;
namespace NameHere.Bll
{
[Shadowing("NameHere.Bll.Account")]
public class Account_Accessor : ProjectBase_Accessor<Account>
{
protected static PrivateType m_privateType;
public Account_Accessor(PrivateObject value);
[Shadowing(".ctor@2")]
public Account_Accessor(DateTime created, string createdBy);
[Shadowing("_notes")]
public string _notes { get; set; }
public static Account_Accessor AttachShadow(object value);
[Shadowing("Create@0")]
public override void Create();
}
}
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.ComponentModel;
using System.Linq.Expressions;
namespace NameHere.Bll
{
[Shadowing("NameHere.Bll.ProjectBase`1")]
public class ProjectBase_Accessor<T> : BaseShadow, INotifyPropertyChanged
{
protected static PrivateType m_privateType;
public ProjectBase_Accessor(PrivateObject value);
[Shadowing("Created")]
public DateTime Created { get; set; }
public static PrivateType ShadowedType { get; }
[Shadowing("add_PropertyChanged@1")]
public void add_PropertyChanged(PropertyChangedEventHandler value);
public static ProjectBase_Accessor<T> AttachShadow(object value);
[Shadowing("Create@0")]
public virtual void Create();
}
}发布于 2012-10-25 01:48:12
问题是,尽管访问器类公开了与它所隐藏的类相同的方法和属性,但访问器和原始类之间没有公共接口。Account_Accessor继承自BaseShadow,Account继承自其他东西。就编译器而言,它们是完全不相关的类型,不兼容赋值,因此很难将每个类型的实例传递到公共例程中。
如果可以强制Account_Accessor类实现也由Account实现的接口类型,则可以将每个接口类型的实例传递给以接口类型作为参数的函数。如下所示:
internal static IAccount SetupAccount(IAccount account, bool saveToDatabase)
{
// do account setup here - not construction
}
// to call: construct instance, then pass to common function
var account = new Account(a, b);
SetupAccount(account, true);如果Account实例的构造足够复杂,以至于您也希望有一个通用的例程,那么可以将特定于类型的包装器放在通用函数之前:
internal static IAccount CreateAccount(bool saveToDatabase)
{
var account = new Account(a,b);
return SetupAccount(account, saveToDatabase);
}
internal static IAccount CreateAccountAccessor(bool saveToDatabase)
{
var account = new Account_Accessor(a,b);
return SetupAccount(account, saveToDatabase);
}您无法避免的一点是:某个地方的某个人必须提交要构造的实例。即使您将其归结为传递类型并使用Activator.CreateInstance(),也必须有人承诺选择要使用的类型。
一旦构造了实例,并且两种类型都实现了公共接口,那么所有需要关心的公共函数就是公共接口。
https://stackoverflow.com/questions/13054481
复制相似问题