私有访问器类忽略通用约束

发布于 2024-07-04 21:22:16 字数 1579 浏览 9 评论 0原文

这些天,我遇到了团队系统单元测试的问题。 我发现自动创建的访问器类会忽略通用约束 - 至少在以下情况下:

假设您有以下类:

namespace MyLibrary
{
 public class MyClass
 {
  public Nullable<T> MyMethod<T>(string s) where T : struct
  {
   return (T)Enum.Parse(typeof(T), s, true);
  }
 }
}

如果要测试 MyMethod,则可以使用以下测试方法创建一个测试项目:

public enum TestEnum { Item1, Item2, Item3 }

[TestMethod()]
public void MyMethodTest()
{
 MyClass c = new MyClass();
 PrivateObject po = new PrivateObject(c);
 MyClass_Accessor target = new MyClass_Accessor(po);

 // The following line produces the following error:
 // Unit Test Adapter threw exception: GenericArguments[0], 'T', on
 // 'System.Nullable`1[T]' violates the constraint of type parameter 'T'..
 TestEnum? e1 = target.MyMethod<TestEnum>("item2");

 // The following line works great but does not work for testing private methods.
 TestEnum? e2 = c.MyMethod<TestEnum>("item2");
}

运行测试将失败上面代码片段的评论中提到的错误。 问题在于 Visual Studio 创建的访问器类。 如果您深入了解,您将看到以下代码:

namespace MyLibrary
{
 [Shadowing("MyLibrary.MyClass")]
 public class MyClass_Accessor : BaseShadow
 {
  protected static PrivateType m_privateType;

  [Shadowing(".ctor@0")]
  public MyClass_Accessor();
  public MyClass_Accessor(PrivateObject __p1);
  public static PrivateType ShadowedType { get; }
  public static MyClass_Accessor AttachShadow(object __p1);

  [Shadowing("MyMethod@1")]
  public T? MyMethod(string s);
 }
}

正如您所看到的,MyMethod 方法的泛型类型参数没有任何约束。

这是一个错误吗? 这是设计使然吗? 谁知道如何解决这个问题?

These days, i came across a problem with Team System Unit Testing. I found that the automatically created accessor class ignores generic constraints - at least in the following case:

Assume you have the following class:

namespace MyLibrary
{
 public class MyClass
 {
  public Nullable<T> MyMethod<T>(string s) where T : struct
  {
   return (T)Enum.Parse(typeof(T), s, true);
  }
 }
}

If you want to test MyMethod, you can create a test project with the following test method:

public enum TestEnum { Item1, Item2, Item3 }

[TestMethod()]
public void MyMethodTest()
{
 MyClass c = new MyClass();
 PrivateObject po = new PrivateObject(c);
 MyClass_Accessor target = new MyClass_Accessor(po);

 // The following line produces the following error:
 // Unit Test Adapter threw exception: GenericArguments[0], 'T', on
 // 'System.Nullable`1[T]' violates the constraint of type parameter 'T'..
 TestEnum? e1 = target.MyMethod<TestEnum>("item2");

 // The following line works great but does not work for testing private methods.
 TestEnum? e2 = c.MyMethod<TestEnum>("item2");
}

Running the test will fail with the error mentioned in the comment of the snippet above. The problem is the accessor class created by Visual Studio. If you go into it, you will come up to the following code:

namespace MyLibrary
{
 [Shadowing("MyLibrary.MyClass")]
 public class MyClass_Accessor : BaseShadow
 {
  protected static PrivateType m_privateType;

  [Shadowing(".ctor@0")]
  public MyClass_Accessor();
  public MyClass_Accessor(PrivateObject __p1);
  public static PrivateType ShadowedType { get; }
  public static MyClass_Accessor AttachShadow(object __p1);

  [Shadowing("MyMethod@1")]
  public T? MyMethod(string s);
 }
}

As you can see, there is no constraint for the generic type parameter of the MyMethod method.

Is that a bug? Is that by design? Who knows how to work around that problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

橘香 2024-07-11 21:22:17

我没有验证所有内容,但看起来像是调用:

TestEnum? e1 = target.MyMethod("item2");

使用类型推断来确定泛型类型参数 T。如果可能,请尝试在测试中以不同方式调用该方法:

TestEnum? e1 = target.MyMethod<TestEnum>("item2");

这可能会产生不同的结果。

希望有帮助!

I didn't verify everything, but it looks like the call to:

TestEnum? e1 = target.MyMethod("item2");

uses type inference to determine the generic type param T. Try calling the method differently in the test if possible:

TestEnum? e1 = target.MyMethod<TestEnum>("item2");

That may yield different results.

Hope that helps!

不及他 2024-07-11 21:22:17

看起来像一个错误。 解决方法是将方法更改为 internal 并将 [ assembly: InternalsVisibleTo("MyLibrary.Test")] 添加到包含被测类的程序集中。

这将是我测试非公开方法的首选方式,因为它会产生看起来更清晰的单元测试。

Looks like a bug. The workaround would be to change the method to internal and add [assembly: InternalsVisibleTo("MyLibrary.Test")] to the assembly containing class under test.

This would be my preferred way of testing non-public methods as it produces much cleaner looking unit tests.

清君侧 2024-07-11 21:22:17

在 msdn 上搜索带有泛型的单元测试。 这是一个已知的限制。 对 Microsoft Connect 的解决方案进行投票,因为它确实需要解决。

Search for unit tests with generics on msdn. This is a known limitation. Vote for a resolution on Microsoft Connect, as it is definately needs resolving.

合约呢 2024-07-11 21:22:17

我投票错误。 我不明白这是怎么设计的。

I vote bug. I don't see how this could be by design.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文