Reputation: 6790
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.
Upvotes: 1
Views: 2561
Reputation: 36
you can do something like this if you want your delegate to point to any method definition:-
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
}
Upvotes: 0
Reputation: 174309
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;
Upvotes: 3