英文:
How can I make this function reusable " foreach loop" in selenium c#?
问题
在上面的循环中,应该可重用,创建了一个Utilities类,不确定如何在需要时调用相同的函数。TIA
英文:
foreach (Residency residency in test.Residencies)
{
if (residency.TestGuid == testGuid)
{
if (requiredResidency == null)
requiredResidency = residency;
else if (requiredResidency.StartDate < residency.StartDate)
requiredResidency = residency;
}
}
the above loop should be reusable, created a Utilities class not sure on how to call the same function in the test when required. TIA
答案1
得分: 1
以下是翻译好的部分:
"requiredResidency" 的声明位置不明确。这使得回答有点困难。
现在,我在实际项目中看到(并执行过)以下操作:
继承
将一组测试共有的功能提取到 "TestBase" 中。
示例:
public abstract class ResidencyTestBase
{
protected Residency GetRequiredResidency(IEnumerable<Residency> testResidencies, Guid testGuid)
{
// TODO 实现
}
}
// 然后你可以有各种不同的测试类,例如
public class SomeResidencyTest : ResidencyTestBase
{
[Fact] // 我们使用 xUnit,但这个想法也适用于其他测试框架。
public void SomeTest()
{
var sut = GetRequiredResidency(testData, testId);
// ...
}
}
public class SomeOtherResidencyTest : ResidencyTestBase
{
[Fact] // 我们使用 xUnit
public void SomeOtherTest()
{
var sut = GetRequiredResidency(testData, testId);
// ...
}
}
"TestHelper" 类
示例:
public static class ResidencyTestHelper
{
// 可以作为测试数据的扩展方法吗?
public static Residency GetRequiredResidency(this IEnumerable<Residency> testData, Guid testId)
{
// 实现
}
}
// 使用方式
var sut = testData.GetRequiredResidency(testId);
您的具体功能
foreach (Residency residency in test.Residencies)
{
if (residency.TestGuid == testGuid) // 可以用 LINQ Where 表达
{
if (requiredResidency == null)
requiredResidency = residency; // 副作用!
else if (requiredResidency.StartDate < residency.StartDate)
requiredResidency = residency;
// 缺失情况:两个条件都不符合...
}
}
因此,我想你可以将其重构如下:
// 作为扩展方法:
// 我们返回引用,因为我们不能依赖副作用
static Residency? GetRequiredResidency(this Residency? requiredResidency,
IEnumerable<Residency> testData, Guid testId)
{
// 这里使用了 Linq,但这也可以用传统的语法表示
var residenciesById = testData.Where(r => r.TestGuid == testGuid);
if (requiredResidency is not null)
residenciesById = residenciesById.Where(r => requiredResidency.StartDate < r.StartDate);
return residenciesById.LastOrDefault() ?? requiredResidency;
// ^^ 这是为了使行为保持一致。如果两个条件都不满足(= 在您的代码中的 "缺失情况"),我们在这里得到 null,因此我们设置它最初的值。
}
// 使用方式
Residency requiredResidency = ...; // 假设在某处已声明...
requiredResidency = requiredResidency.GetRequiredResidency(test.Residencies, testId);
英文:
It is unclear, where requiredResidency
is declared. That makes it a little hard to give an answer.
Now, what I have seen (and done) in actual projects are these:
Inheritance
Functionality, that is common to a set of tests is drawn into a "TestBase".
Example:
public abstract class ResidencyTestBase
{
protected Residency GetRequiredResidency( IEnumerable<Residency> testResidencies, Guid testGuid )
{
// TODO Implementation
}
}
// and then you'd have various tests like
public class SomeResidencyTest : ResidencyTestBase
{
[Fact] // we are using xUnit but the idea applies to other
// Test Frameworks, too.
public void SomeTest()
{
var sut = GetRequiredResidency( testData, testId );
// ...
}
}
public class SomeOtherResidencyTest : ResidencyTestBase
{
[Fact] // we are using xUnit
public void SomeOtherTest()
{
var sut = GetRequiredResidency( testData, testId );
// ...
}
}
"TestHelper" class(es)
Example:
public static class ResidencyTestHelper
{
// maybe as extension method on the test data?
public static Residency GetRequiredResidency(this IEnumerable<Residency> testData, Guid testId)
{
// impl.
}
}
// Usage
var sut = testData.GetRequiredResidency( testId );
Your specific functionality
foreach (Residency residency in test.Residencies)
{
if (residency.TestGuid == testGuid) // can be expressed as a LINQ Where
{
if (requiredResidency == null)
requiredResidency = residency; // Sideeffect!
else if (requiredResidency.StartDate < residency.StartDate)
requiredResidency = residency;
// Missing case: both conditions fail ...
}
}
So, I guess one could refactor this like so:
// As ExtensionMethod:
// We _return_ the reference, because we cannot rely on sideeffects
static Residency? GetRequiredResidency ( this Residency? requiredResidency,
IEnumerable<Residency> testData, Guid testId )
{
// Linq is used here, but this can also be expressed in plain old syntax
var residenciesById = testData.Where(r => r.TestGuid == testGuid);
if( requiredResidency is not null )
residenciesById = residenciesById.Where(r => requiredResidency.StartDate < r.StartDate );
return residenciesById.LastOrDefault() ?? requiredResidency;
// ^^ this is to make the behavior the same. If both conditions fail
// (= "missing case" in your code, your code does not change the
// original, so) we get null here, so we set what it originally was.
}
// Usage
Residency requiredResidency = ...; // Assume declared somewhere...
requiredResidency = requiredResidency.GetRequiredResidency( test.Residencies, testId );
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论