I have to begin by apologising if the terms I use are incorrect. I use groovy/java for automation tasks only(Gradle), and I don't have years of experience delivering production grade software.
So, the challenge that I have is as follows: I have a spec which is trying to test a return string is as expected (almost identical to this).
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Stub()
stubCert.getSubjectDN().toString() >> "Test"
when:
def output = X509CertificateUtils.prettyPrint(stubCert)
then:
output == "Subject: Test"
}
However, the difference is that my method constraint returns a Principal object, and its that object's toString() that I really want to stub. I thought I was doing that correctly above, but it doesn't give the result I expect.
Here's my helper class.
import java.security.cert.X509Certificate
class X509CertificateUtils {
static def prettyPrint(X509Certificate x509Certificate) {
return "Subject: ${x509Certificate.getSubjectDN()}"
}
}
If I run this test I get the following error:
output == "Subject: Test"
| |
| false
| 38 differences (20% similarity)
| Subject: (Mock for )t(ype 'Principal' named 'dummy')
| Subject: (Tes------)t(-----------------------------)
Subject: Mock for type 'Principal' named 'dummy'
Any help would be gratefully received.
Just create a second stub:
X509Certificate stubCert = Stub()
Principal princ = Stub()
princ.toString() >> "Test"
stubCert.getSubjectDN() >> princ
Spock has a few approaches to faking objects. Here's the current documentation.
My question for you... Are you attempting to test that prettyPrint() alone is working properly, that SubjectDN.toString() prints properly, or a combination of the two? My suggestion is to have your mock return an actual SubjectDN() object that you then test as well. Not much more work, and if something breaks you have a better idea of where the problem originated. Max's solution will solve your question; I didn't read close enough or follow good test scoping practices. I'll leave the rest of my answer as food for thought. If you want to mix Max's stub approach with my parameterization I would suggest passing the desired string in the where block to the stub creation in the setup block.
This is beginning to get off topic, but if you need to test more than one SubjectDN scenario (null, empty, various capitalizations, numerics, etc); you should look into parameterizing your test as well.
def "pretty print returns correct string"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> subject
expect:
subject.toString() == expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
subject | expectedToString | expectedFormatted
new SubjectDN("") | ???? | "Subject: ????"
new SubjectDN(null) | ???? | "Subject: ????"
new SubjectDN("test") | "test" | "Subject: Test"
new SubjectDN("testing") | "testing" | "Subject: Testing"
}
If your pretty printing really is as simple as prepending "Subject: " you could probably get away with computing your expectedFormatted variable; but you really shouldn't have your test mimic the code you're testing in an attempt to make testing easier.
I also find that the table format of parameterizing the tests gets messy or difficult to maintain when the the iterations have a fluid length. My preference is to make a list of maps, with each map representing a test iteration. It keeps each test iteration bundled together and gives unfamiliar developers a better idea of what each iteration of the test entails.
@Unroll(iteration.testName) // Shows each iteration in its own result (in most IDEs)
def "testing printing of a SubjectDN"() {
setup:
X509Certificate stubCert = Mock()
stubCert.getSubjectDN() >> iteration.subject
expect:
subject.toString() == iteration.expectedToString
X509CertificateUtils.prettyPrint(stubCert) == expectedFormatted
where:
iteration << [
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("test"),
expectedToString: "test"],
[testName: "Testing pretty printing a normal SubjectDN",
subject: new SubjectDN("testing 123"),
expectedToString: "testing 123"],
[testName: "Testing pretty printing a null SubjectDN",
subject: new SubjectDN(null),
expectedToString: ????]
// And so on...
]
expectedFormatted = "Subject: ${iteration.expectedToString}"
}
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