![](/img/trans.png)
[英]Is there a way I can do a foreach that contains code in a LINQ expression?
[英]How can I rewrite this foreach to be a part of the previous Linq expression?
我正在用自定義屬性, SpecificationAttribute
和VerificationAttribute
裝飾我的MSTest測試,以后將它們用於生成html測試規范報告。
屬性如下所示:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class SpecificationAttribute : Attribute
{
public SpecificationAttribute(int step, string text)
{
Step = step;
Text = text;
}
public int Step { get; set; }
public string Text { get; set; }
}
我編寫了一個測試,該測試斷言測試方法在使用屬性時必須具有唯一的步驟。 例如,以下用法未能通過我的測試,因為它應該:
[Specification(1, "Click Button)]
[Verification(1, "Verify popup")]
[Specification(1, "Click close")]
[Verification(2, "Verify popup disappears")]
我的測試看起來像這樣:
[TestMethod]
public void TestForNoDuplicateStepsOnMethod()
{
var specificationMethods = Assembly.GetExecutingAssembly().GetTypes()
.Where(type =>
type.GetCustomAttribute<CompilerGeneratedAttribute>() == null &&
type.GetCustomAttribute<TestClassAttribute>() != null)
.SelectMany(type => type.GetMethods())
.Where(methodInfo =>
methodInfo.GetCustomAttribute<TestMethodAttribute>() != null &&
methodInfo.GetCustomAttributes<SpecificationAttribute>().Any())
.ToArray();
foreach (var method in specificationMethods)
{
var specificationAttributes = method.GetCustomAttributes<SpecificationAttribute>();
var duplicates = specificationAttributes.GroupBy(s => s.Step).Where(grp => grp.Count() > 1).SelectMany(x => x).ToList();
if (duplicates.Any())
{
var initialMessage = $@"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number." + Environment.NewLine + Environment.NewLine;
var message = duplicates.Aggregate(initialMessage, (s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine);
Assert.Fail(message);
}
}
}
我想重寫最后一部分,使其成為Linq查詢的一部分。 這可能嗎? 另外,我當前的測試僅輸出一種失敗的方法。 如果Linq查詢可以包括在唯一步驟號上具有失敗條件的所有方法,那將是可取的。
如果您不需要對var SpecificationMethods進行更多操作,則可以嘗試以下操作:
[TestMethod]
public void TestForNoDuplicateStepsOnMethod()
{
Assembly.GetExecutingAssembly().GetTypes()
.Where(type =>
type.GetCustomAttribute<CompilerGeneratedAttribute>() == null &&
type.GetCustomAttribute<TestClassAttribute>() != null)
.SelectMany(type => type.GetMethods())
.Where(methodInfo =>
methodInfo.GetCustomAttribute<TestMethodAttribute>() != null &&
methodInfo.GetCustomAttributes<SpecificationAttribute>().Any())
.ToList().ForEach (method=>
{
var specificationAttributes = method.GetCustomAttributes<SpecificationAttribute>();
var duplicates = specificationAttributes.GroupBy(s => s.Step).Where(grp => grp.Count() > 1).SelectMany(x => x).ToList();
if (duplicates.Any())
{
var initialMessage = $@"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number." + Environment.NewLine + Environment.NewLine;
var message = duplicates.Aggregate(initialMessage, (s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine);
Assert.Fail(message);
}
}
}
}
(經過編輯以通過積極的測試解決該問題)嘗試此操作,但是恕我直言,它很難閱讀。
[TestMethod]
public void TestForNoDuplicateStepsOnMethod()
{
var errors = Assembly.GetExecutingAssembly().GetTypes()
.Where(type =>
type.GetCustomAttribute<CompilerGeneratedAttribute>() == null &&
type.GetCustomAttribute<TestClassAttribute>() != null)
.SelectMany(type => type.GetMethods())
.Where(methodInfo =>
methodInfo.GetCustomAttribute<TestMethodAttribute>() != null &&
methodInfo.GetCustomAttributes<SpecificationAttribute>().Any())
.Select(method =>
method.GetCustomAttributes<SpecificationAttribute>()
.GroupBy(s => s.Step)
.Where(grp => grp.Count() > 1)
.Select(x => x.Aggregate(
$@"{Environment.NewLine}{method.DeclaringType}.{method.Name} contains several SpecificationAttribute with the same step number."
+ Environment.NewLine,
(s, attribute) => s + attribute.Step + " " + attribute.Text + Environment.NewLine))
.Aggregate("", (s, message) => s + message))
.Aggregate("", (s, message) => s + message);
Assert.AreEqual("", errors);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.