首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新两个公共函数以使用共享函数的最佳方法

更新两个公共函数以使用共享函数的最佳方法
EN

Stack Overflow用户
提问于 2012-10-25 01:25:58
回答 1查看 222关注 0票数 2

如果需要测试另一个项目中的非公共属性,则Microsoft单元测试向导会创建访问器对象。在我的单元测试中,我创建助手函数,这样我就不会在每个单元测试方法中重复相同的代码。目前,我有两个几乎相同的测试,除了一个采用标准公共对象,另一个采用访问器版本。因为访问器是基于公共对象的,所以我应该有一个函数。我曾假设我可以使用泛型通过简单的强制转换来完成。但在posting the question之后,我发现还有更多的工作要做,包括必须更新底层对象。我的问题是,另一种方法可以将这些冗余方法减少到只有一个函数使用强制转换(或另一个)方法?

下面是现有的两个函数:

代码语言:javascript
复制
// 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创建的访问器代码(同样,为了简化示例,我对其进行了精简):

代码语言:javascript
复制
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();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-10-25 01:48:12

问题是,尽管访问器类公开了与它所隐藏的类相同的方法和属性,但访问器和原始类之间没有公共接口。Account_Accessor继承自BaseShadow,Account继承自其他东西。就编译器而言,它们是完全不相关的类型,不兼容赋值,因此很难将每个类型的实例传递到公共例程中。

如果可以强制Account_Accessor类实现也由Account实现的接口类型,则可以将每个接口类型的实例传递给以接口类型作为参数的函数。如下所示:

代码语言:javascript
复制
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实例的构造足够复杂,以至于您也希望有一个通用的例程,那么可以将特定于类型的包装器放在通用函数之前:

代码语言:javascript
复制
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(),也必须有人承诺选择要使用的类型。

一旦构造了实例,并且两种类型都实现了公共接口,那么所有需要关心的公共函数就是公共接口。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13054481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档