gpt4 book ai didi

c# - 更新两个常用函数以使用共享函数的最佳方法

转载 作者:行者123 更新时间:2023-11-30 22:23:58 26 4
gpt4 key购买 nike

如果您需要测试另一个项目的非公共(public)属性,Microsoft 单元测试向导会创建访问器对象。在我的单元测试中,我创建了辅助函数,这样我就不会在每个单元测试方法中重复相同的代码。目前我有两个几乎相同的测试,除了一个采用标准公共(public)对象,另一个采用访问器版本。由于访问器基于公共(public)对象,因此我应该能够拥有一个功能。我曾假设我可以使用泛型来完成一个简单的转换。但是在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();
}

我有两打这样的单元测试,真实对象平均有 10 个属性,我在这里简化了示例。

这是单元测试 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();
}
}

最佳答案

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

如果您可以强制 Account_Accessor 类实现一个同样由 Account 实现的接口(interface)类型,那么您可以将每个实例传递给以该接口(interface)类型作为参数的函数。像这样:

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(),也必须有人 promise 选择要使用的类型。

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

关于c# - 更新两个常用函数以使用共享函数的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13054481/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com