56

TestCase を使用してジェネリック型を NUnit のテストに渡す方法はありますか?

これは私がやりたいことですが、構文が正しくありません...

[Test]
[TestCase<IMyInterface, MyConcreteClass>]
public void MyMethod_GenericCall_MakesGenericCall<TInterface, TConcreteClass>()
{
    // Arrange

    // Act
    var response = MyClassUnderTest.MyMethod<TInterface>();

    // Assert
    Assert.IsInstanceOf<TConcreteClass>(response);
}

または、そうでない場合、同じ機能を実現するための最良の方法は何ですか (明らかに、実際のコードには複数の TestCase があります)。

別の例で更新...

これは、単一のジェネリック型が渡された別の例です...

[Test]
[TestCase<MyClass>("Some response")]
public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
    // Arrange

    // Act
    var response = MyClassUnderTest.MyMethod<T>();

    // Assert
    Assert.AreEqual(expectedResponse, response);
}
4

9 に答える 9

10

カスタム GenericTestCaseAttribute を作成できます

[Test]
[GenericTestCase(typeof(MyClass) ,"Some response", TestName = "Test1")]
[GenericTestCase(typeof(MyClass1) ,"Some response", TestName = "Test2")]
public void MapWithInitTest<T>(string expectedResponse)
{
    // Arrange

    // Act
    var response = MyClassUnderTest.MyMethod<T>();

    // Assert
    Assert.AreEqual(expectedResponse, response);
}

これが GenericTestCaseAttribute の実装です

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class GenericTestCaseAttribute : TestCaseAttribute, ITestBuilder
{
    private readonly Type _type;
    public GenericTestCaseAttribute(Type type, params object[] arguments) : base(arguments)
    {
        _type = type;
    }

    IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
    {
        if (method.IsGenericMethodDefinition && _type != null)
        {
            var gm = method.MakeGenericMethod(_type);
            return BuildFrom(gm, suite);
        }
        return BuildFrom(method, suite);
    }
}
于 2016-11-15T20:46:03.523 に答える
7

C# の属性はジェネリックにできないため、思いどおりに操作することはできません。おそらく最も簡単なTestCase方法は、リフレクションを使用して実際のメソッドを呼び出すヘルパー メソッドに属性を配置することです。このようなものはうまくいくかもしれません(注、テストされていません):

    [TestCase(typeof(MyClass), "SomeResponse")]
    public void TestWrapper(Type t, string s)
    {
        typeof(MyClassUnderTest).GetMethod("MyMethod_GenericCall_MakesGenericCall").MakeGenericMethod(t).Invoke(null, new [] { s });
    }
于 2010-03-02T19:13:16.610 に答える
7

最初にテストから始めてください。テストするときも同様です。何をしたいですか?おそらく次のようなものです:

[Test]
public void Test_GenericCalls()
{
    MyMethod_GenericCall_MakesGenericCall<int>("an int response");
    MyMethod_GenericCall_MakesGenericCall<string>("a string response");
      :
}

次に、テストを単純な古い機能テストにすることができます。[テスト] マーカーがありません。

public void MyMethod_GenericCall_MakesGenericCall<T>(string expectedResponse)
{
    // Arrange

    // Act
    var response = MyClassUnderTest.MyMethod<T>();

    // Assert
    Assert.AreEqual(expectedResponse, response);
}
于 2010-03-02T19:10:22.807 に答える
4

私は先週似たようなことをしました。これが私が最終的に得たものです:

internal interface ITestRunner
{
    void RunTest(object _param, object _expectedValue);
}

internal class TestRunner<T> : ITestRunner
{
    public void RunTest(object _param, T _expectedValue)
    {
        T result = MakeGenericCall<T>();

        Assert.AreEqual(_expectedValue, result);
    }
    public void RunTest(object _param, object _expectedValue)
    {
        RunTest(_param, (T)_expectedValue);
    }
}

そして、テスト自体:

[Test]
[TestCase(typeof(int), "my param", 20)]
[TestCase(typeof(double), "my param", 123.456789)]
public void TestParse(Type _type, object _param, object _expectedValue)
{
    Type runnerType = typeof(TestRunner<>);
    var runner = Activator.CreateInstance(runnerType.MakeGenericType(_type));
    ((ITestRunner)runner).RunTest(_param, _expectedValue);
}
于 2010-03-02T19:17:19.500 に答える
2

オブジェクトを返すジェネリック関数でテストしているかもしれませんか?例:

public Empleado TestObjetoEmpleado(Empleado objEmpleado) 
{
    return objEmpleado; 
}

ありがとう

于 2010-12-06T18:50:01.033 に答える