存储一个委托方法类的一个成员(Store a delegate method as a member

2019-10-16 16:37发布

我在做编码的UI测试,对UI基本单元测试,我创建了一个TestObject存储要实例化它TestMethod的范围内对自身进行断言的列表类。

public class TestObject {
    public string urlToTest;
    public List<Assertion> assertions;
}

public class Assertion {
    public List<SearchPropertyExpression> searchPropertyExpressions;
    public Action assertMethod;
    public string expectedValue; // <-- this works fine if I'll always call a method like AreEqual() where it has an expected value, but what if I want to store a method in assertMethod that has different arguments???
}

public class SearchPropertyExpression {
    public string expression;
    public string value;
}

我想用来存储断言方法(例如: Assert.AreEqaul(object expected, object actual) ,我想针对特定执行TestObject和后来打电话,但我努力得到的东西,是语法正确的我。也与如何来传递参数对于委托方法(挣扎assertMethod )时,它实际上调用。所有的方法,我会打电话的内Microsoft.VisualStudio.TestTools.UnitTesting.Assert 。在下面的例子中,我想打电话给Assert.AreEqaul()但具有可变参数的任何方法可以被调用。这里就是我这么远...

[TestMethod]
public void uiTestConnectionsEducationHomePage() {
    //instantiate test object
    TestObject testObject = new TestObject() {
        urlToTest = "/example/home.aspx",
        assertions = {
            new Assertion() {
                searchPropertyExpressions = {
                    new SearchPropertyExpression() {
                        expression = HtmlDiv.PropertyNames.Id,
                        value = "header"
                    }
                },
                assertMethod = Assert.AreEqual // <-- this is wrong,I'm thinking I need to tell assertMethod what arguments to expect here, lambda??
            }
        }
    };

    // get handle to browser and launch
    UiBrowserWindow uiBrowserWindow = new UiBrowserWindow();
    uiBrowserWindow.launchUrl(testObject.urlToTest);

    // assertions
    testObject.assertions.ForEach(x => {
        HtmlDiv htmlObject = new HtmlDiv();
        x.searchPropertyExpressions.ForEach(p => {
            htmlObject = uiBrowserWindow.uiHtmlDocument.searchHtmlElementByAttributeValue<HtmlDiv>(p.expression, p.value);
        });
        x.assertMethod; // <-- for this is example the arguments would be (htmlObject, "header").                   
    });
}

我想我真正的问题是,这里有一个设计模式,可以真正帮助我,但我没有很好地设计模式精通。

Answer 1:

您的assertMethod委托是类型的Action ,其代表具有的空隙的返回类型和任何参数,例如方法void Foo()
Assert.AreEqual有许多重载 ,最universial存在Assert.AreEqual(Object expected, Object actual) 。 我建议你使用这个并相应地改变你的委托:

Action<Object, Object> assertMethod;


Answer 2:

如果你希望你的委托来指向任何方法定义,你可以做这样的事情: -

public delegate void MyAction(params object[] args);
public class Assertion
{
    public List<PropertyExpression> propertyExpressions;
    public MyAction assertMethod;
}
public void Test()
{
   var asser = new Assertion()
                    {
                        assertMethod = (vals) =>Assert.AreEqual(vals[0],vals[1]);
                        propertyExpressions = null
                    };
   var asser2 = new Assertion()
                    {
                        assertMethod = (vals)=>Assert.AreEqual((string)vals[0],(string)vals[1],(bool)vals[2]);
                        propertyExpressions = null
                    };

    asser.assertMethod(1, 1);//calling object,object overload
    asser2.assertMethod("ab", "cd", true);//calling string,string,bool overload
}


文章来源: Store a delegate method as a member of class
标签: c# delegates