I'm trying to write a Specs2 test that will test a snippet's output in response to different parameters which would normally be passed in from a template, but I haven't been able to figure out how to do it.
For instance, with the snippet callout in this div:
<div class="lift:Snippet.method?param1=foo"></div>
I'm passing the parameter param1 to the snippet. My snippet would look something like this:
class Snippet {
def method(in:NodeSeq):NodeSeq = {
val param1 = S.attr("param1") openOr ""
param1 match {
case "foo" => //do something
case "bar" => //do something else
case _ => //do yet another thing
}
}
}
So within my test, I want to test how the snippet responds to different param1 values
class SnippetTest extends Specification {
"Snippet" should {
"do something" in {
val html = <ul>
<li class="first">
<li class="second">
<li class="third">
</ul>
//I need to set param1 here somehow
val out = Snippet.method(html)
//then check that it did what it was supposed to
out.something must be "xyz"
}
}
}
How do I set param1?
I am a big time scala and lift newb (coming from python+django), so if I'm barking up the wrong tree, please direct me to the right one. I think that might be the case, I've been googling on this all day and haven't found any questions remotely similar to this one.
Thanks,
Blake
Ok, I've gotten this figured out. This question hasn't seen much interest, but in case anyone is out there googling with the same problem / question, here is how you do it:
Lift's "S" object needs to have our arbitrary attributes added to it so that it will give our snippet the attributes we want to test when asked. Unfortunately, there are 2 problems. First, the "S" object is only initialized when an http request is received. Second, S.attr is immutable.
Lift has a package called mockweb which allows you to make mock http requests. The documentation for this package typically talks about testing sessions and user logins and whatnot, but it also provides mechanisms for initializing "S" as part of a specification test.
The first problem, initializing S, is solved by defining our test class as an extension of WebSpec instead of Specification (WebSpec is part of the mockweb package and extends Specification), and calling "withSFor" during the specification definition, which will initialize "S"
The second problem, dealing with S.attr being immutable is solved with the "S" method "withAttrs". "withAttrs" executes a block of code you provide with both it's regular attributes, and attributes provided by you in a map. Your arbitrary attributes are only available from S.attr temporarily
Here is the test from my original question which has been modified to solve the 2 problems:
import net.liftweb.mockweb._
class SnippetTest extends WebSpec {
"Snippet" should {
"do something" withSFor("/") in {
val html = <ul>
<li class="first">
<li class="second">
<li class="third">
</ul>
//here I set param1
var m = new HashMap[String, String]
m += "param1" -> "foo"
val s = new Snippet()
//then tell S to execute this block of code
//with my arbitrary attributes.
//'out' will be the NodeSeq returned by s.method
val out = S.withAttrs(S.mapToAttrs(m)){
s.method(html)
}
//then check that it did what it was supposed to
out.something must be "xyz"
}
}
}
edit: clarity
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With