将委托方法存储为类的成员 [英] Store a delegate method as a member of class

查看:107
本文介绍了将委托方法存储为类的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做ui测试,基本上是对ui进行单元测试,而且我创建了一个 TestObject 类,该类存储要针对自身执行的断言列表TestMethod实例化。

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

public class Assertion {
public List< SearchPropertyExpression> searchPropertyExpressions
public Action assertMethod;
public string expectedValue; //< - 如果我总是调用像AreEqual()这样的方法,它有一个预期的值,但如果我想存储一个方法在assertMethod有不同的参数怎么办?
}

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

我想存储assert方法(例如: Assert.AreEqaul(对象预期,对象实际),我想针对特定的 TestObject 执行,并稍后调用,但我正在努力得到一些语法正确的东西,当我们实际调用它时,我也在努力地传递代理方法( assertMethod )的参数,所有的方法调用在 Microsoft.VisualStudio.TestTools.UnitTesting.Assert 中。在下面的示例中,我想调用 Assert.AreEqaul()但是可以调用任何具有不同参数的方法,这就是我到目前为止...

  [TestMethod ] 
public void uiTestConnectionsEducationHomePage(){
//实例化测试对象
TestObject testObject = new TestObject(){
urlToTest =/example/home.aspx,
assertions = {
n ew Assertion(){
searchPropertyExpressions = {
new SearchPropertyExpression(){
expression = HtmlDiv.PropertyNames.Id,
value =header
}
},
assertMethod = Assert.AreEqual //< - 这是错误的,我想我需要告诉assertMethod这里有什么参数,lambda?
}
}
};

//获取浏览器的句柄并启动
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; //< - 为此是例子(htmlObject,header)。
});
}

我认为我真正的问题是这里有一个设计模式,真的可以帮助我,但我不太熟练的设计模式。

解决方案

您的 assertMethod delegate的类型为 Action ,表示返回类型为void并且没有参数的方法,例如 void Foo()

Assert.AreEqual has 许多重载,最多普遍是 Assert.AreEqual(Object expected,Object actual)。我建议你使用它并相应地更改你的委托:

  Action< Object,Object> assertMethod; 


I'm doing coded ui testing, basically unit testing for the ui, and I have created a TestObject class that stores a list of assertions to be performed against itself within the TestMethod that instantiates it.

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;
}

I would like to store the assert method (for example: Assert.AreEqaul(object expected, object actual) that I want executed against that particular TestObject and call that later but I'm struggling to get something that is syntactically correct. I'm also struggling with how to pass the arguments for that delegate method (assertMethod) when it's actually called. All methods that I'll be calling are within Microsoft.VisualStudio.TestTools.UnitTesting.Assert. In the example below I would like to call Assert.AreEqaul() but any method with varying arguments could be called. Here's what I've got so far...

[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").                   
    });
}

I think my real problem is that there is a design pattern here that could really help me but I'm not well versed in design patterns.

解决方案

Your assertMethod delegate is of type Action which represents a method with a return type of void and no parameters, e.g. void Foo().
Assert.AreEqual has many overloads, the most universial being Assert.AreEqual(Object expected, Object actual). I suggest you use this and change your delegate accordingly:

Action<Object, Object> assertMethod;

这篇关于将委托方法存储为类的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆