如何防止通用参数被VS2008单元测试搞砸

时间:2022-12-20 23:22:08

I have two classes like this (in the actual project):

我有两个这样的类(在实际项目中):

namespace app {
    internal class A {
    }

    internal class B {
        private List<A> list;
        private void SomeMethodToTest() {
            list = new List<A>() { new A() };
        }
    }

The I have my Unit test looking something like

我的单元测试看起来像

[TestClass()]
public class ATest {
    [TestMethod()]
    public void TestSomeMethod() {
        B_Accessor b = new B_Accessor();
        b.SomeMethodToTest();
        Assert.AreEqual(1, b.list.Count); // ERROR ON THIS LINE
    }
}

On the marked line I get an InvalidCastException saying something like "unable to cast object of type System.Collections.Generic.List'1[app.A] to type System.Collections.Generic.List'1[app.A_Accessor]

在标记的行上,我得到一个InvalidCastException,说“无法将类型为System.Collections.Generic.List'1 [app.A]的对象强制转换为类型System.Collections.Generic.List'1 [app.A_Accessor]

The problem is that, because A is internal, the auto-generated class B_Accessor looks like

问题是,因为A是内部的,所以自动生成的类B_Accessor看起来像

[Shadowing("app.B")]
public class B_Accessor : BaseShadow {
    ... stuff ...

    [Shadowing("list")]
    public List<A_Accessor> list { get; set; }

    ... stuff ...
}

Note that, in the Accessor class, the list is of type List<A_Accessor> and not List<A>. I have specified the InternalsVisibleTo attribute on the application, so the test project can access the type A, but for some reason VS replaces it with the accessor type, which makes the type incompatible with the wrapped type.

请注意,在Accessor类中,列表的类型为List ,而不是List 。我在应用程序上指定了InternalsVisibleTo属性,因此测试项目可以访问类型A,但由于某种原因,VS将其替换为访问者类型,这使得该类型与包装类型不兼容。

How can I work around this other than making A public?

除了公开宣传之外,我该如何解决这个问题呢?

2 个解决方案

#1


I've deleted my previous answer because I hadn't noticed that you were already using InternalsVisibleToAttribute.

我删除了之前的答案,因为我没有注意到你已经在使用InternalsVisibleToAttribute了。

What's generating these "accessor" classes? When you say "VS replaces it with the accessor type" do you mean it changes your source code? That sounds very odd - what happens if you put it back to just use A and B instead of A_Accessor and B_Accessor?

是什么产生了这些“访问者”类?当你说“VS用访问者类型替换它”时,你的意思是它改变了你的源代码吗?这听起来很奇怪 - 如果你把它放回去使用A和B而不是A_Accessor和B_Accessor会发生什么?

If you can possibly get rid of autogenerated classes which are meant to look like the real ones, but don't quite, then do get rid of them. I suspect this is just one situation where they'll cause problems.

如果你可以摆脱那些看起来像真正的类的自动生成的类,但不完全,那么就去掉它们。我怀疑这只是一种会导致问题的情况。

I've never had any problems just using InternalsVisibleTo and testing internal members directly. (Well, R# sometimes got confused in a previous version, but apart from that...)

我使用InternalsVisibleTo并直接测试内部成员时从未遇到任何问题。 (好吧,R#有时会在以前的版本中混淆,但除此之外......)

#2


It is possible to replace the test project with something like

可以用类似的东西替换测试项目

internal static class AccessorExtensionMethods {
    internal static List<A> Get_list(this PrivateObject po) {
        return (List<A>)po.GetField("list");
    }
}

[TestClass()]
public class ATest {
    [TestMethod()]
    public void TestSomeMethod() {
        PrivateObject bpo = new PrivateObject(new B());
        B_Accessor b = new B_Accessor(bpo);
        b.SomeMethodToTest();
        Assert.AreEqual(1, bpo.Get_list().Count);
    }
}

#1


I've deleted my previous answer because I hadn't noticed that you were already using InternalsVisibleToAttribute.

我删除了之前的答案,因为我没有注意到你已经在使用InternalsVisibleToAttribute了。

What's generating these "accessor" classes? When you say "VS replaces it with the accessor type" do you mean it changes your source code? That sounds very odd - what happens if you put it back to just use A and B instead of A_Accessor and B_Accessor?

是什么产生了这些“访问者”类?当你说“VS用访问者类型替换它”时,你的意思是它改变了你的源代码吗?这听起来很奇怪 - 如果你把它放回去使用A和B而不是A_Accessor和B_Accessor会发生什么?

If you can possibly get rid of autogenerated classes which are meant to look like the real ones, but don't quite, then do get rid of them. I suspect this is just one situation where they'll cause problems.

如果你可以摆脱那些看起来像真正的类的自动生成的类,但不完全,那么就去掉它们。我怀疑这只是一种会导致问题的情况。

I've never had any problems just using InternalsVisibleTo and testing internal members directly. (Well, R# sometimes got confused in a previous version, but apart from that...)

我使用InternalsVisibleTo并直接测试内部成员时从未遇到任何问题。 (好吧,R#有时会在以前的版本中混淆,但除此之外......)

#2


It is possible to replace the test project with something like

可以用类似的东西替换测试项目

internal static class AccessorExtensionMethods {
    internal static List<A> Get_list(this PrivateObject po) {
        return (List<A>)po.GetField("list");
    }
}

[TestClass()]
public class ATest {
    [TestMethod()]
    public void TestSomeMethod() {
        PrivateObject bpo = new PrivateObject(new B());
        B_Accessor b = new B_Accessor(bpo);
        b.SomeMethodToTest();
        Assert.AreEqual(1, bpo.Get_list().Count);
    }
}