10

基本的に、私のテストのいくつかは成功しており、いくつかは失敗しています。スキート氏の素晴らしい提案に従って、私が狂っていないことを確認するために完全なコード サンプルを作成しました。これはコードです:

namespace ClassLibrary
{
    using System;

    public class Manager
    {
        private int SampleMethod(int id)
        {
            return id;
        }
    }
}

私のテストは次のとおりです。

namespace UnitTestProject
{
    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    [TestClass]
    public class UnitTest
    {
        [TestMethod]
        public void TestPasses()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var actual = privateInfo.Invoke("SampleMethod", 1);
        }

        [TestMethod]
        public void TestErrorsOut()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var actual = privateInfo.Invoke("SampleMethod", 0);
        }

        [TestMethod]
        public void TestWorksAsWell()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            privateInfo.Invoke("SampleMethod", new object[] { 0 });
        }

        [TestMethod]
        public void TestAlsoErrorsOut()
        {
            var privateInfo = new PrivateObject(new ClassLibrary.Manager());
            var types = new Type[] { typeof(int) };
            var actual = privateInfo.Invoke("SampleMethod", types, 0);
        }
    }
}

最初のテスト (TestPasses()) は機能します。

2 番目のテスト (TestErrorsOut()) は次のエラーで失敗します: {"Method 'ClassLibrary.Manager.SampleMethod' not found."}

不可解なことは、エラーが一貫していることですが、実際のテストはほとんど同じです。意味がない。VS2012 RC と VS2010 でこれを試しましたが、結果は同じでした。

私が考えることができる唯一のことは、「0」が int 以外の何かとしてキャストされていることです。つまり、SampleMethod のメソッド シグネチャが見つからないということですか? 探している型 (TestAlsoErrorsOut()) を明示的に渡すために 3 番目のテストを試みましたが、それも同じエラーでエラーになります。

アイデア?ありがとう。

編集して追加

params obj[] オーバーロードの代わりに obj[] を使用するという Ian の提案を使用することで、機能します (TestWorksAsWell() をテストします)。Type[] では機能しない params メソッドを使用しているため、TestAlsoErrorsOut() が失敗する理由が説明されています。したがって、これは修正されています。しかし、なぜ?なぜ params obj[] は 1 を渡したときに機能するのに 0 を渡さないのですか?

4

3 に答える 3

13

ドキュメント ( http://msdn.microsoft.com/en-us/library/ms243710.aspx ) によると、引数はオブジェクトの配列として渡されることになっています。オブジェクト配列を明示的に渡すと、正しく機能するように見えます。

var actual = (int)privateInfo.Invoke("SampleMethod", new object[] {0});

単独で 0 を渡すと、コンパイラがこのオーバーロードを選択するように見えます

Invoke(string name = "SampleMethod", System.Reflection.BindingFlags bindingFlags = Default, object[] args = {object[0]})
于 2012-07-25T11:40:51.200 に答える