junit4 icon indicating copy to clipboard operation
junit4 copied to clipboard

@TheoryRule for theories

Open santeriv opened this issue 13 years ago • 9 comments

Currently doing this

@Datapoints
function Browser[] getBrowserAndStuff()

@Theory
function void theoryBrowse( Browser browser )
{
setStuff( browser.getStuff() );
stuff.do();
}

@Theory
function void theoryBrowseMore( Browser browser )
{
setStuff( browser.getStuff() );
stuff.do();
}

I think this should be easy as this:


@BeforeTheory
function void myTheorySetup( Browser browser )
{
setStuff( browser.getStuff() );
}

@Theory
function void theoryBrowseMore( Browser browser )
{
stuff.do();
}
@Theory
function void theoryBrowseMore( Browser browser )
{
stuff.do();
}

Or @BeforeTheory could be used like this :

@Datapoints -> @BeforeTheory -> @Test (as it is parameterless it relies on setup done in @BeforeTheory)

What do you think, has there been thinking / discussion about to having @BeforeTheory ?

santeriv avatar Sep 22 '11 09:09 santeriv

I think that you can get a similar effect by passing the Browser into a constructor on the Test class. Can you try that? And if it works, can you raise a separate bug to document that feature better? ;-)

dsaff avatar Sep 22 '11 14:09 dsaff

@Datapoints
function Browser[] getBrowserAndStuff() 

Sorry, I forgot to mention that datapoints method is located in an abstract base class which is shared by lots of other similiar test classes. IMO, Otherwise using a constructor could work in simpler case. So, Datapoints -> BeforeTheory -> Theory is what we are aiming for.

santeriv avatar Oct 17 '11 07:10 santeriv

What would you think about a @TheoryRule?


@TheoryRule TestRule my TheorySetup = new TheoryRule() {
  Statement apply(Statement base, Description description, Browser browser) {
    setStuff( browser.getStuff() );
    base.evaluate();
  }
}

@Theory
function void theoryBrowseMore( Browser browser )
{
stuff.do();
}

Not sure on the syntax. Thoughts?

dsaff avatar Oct 17 '11 20:10 dsaff

Didn't know that there exists @Rule s in junit - I guess you ment that by this new @TheoryRule .. To us it sounds good enough. +2

If those Rules can be written in that abstract base class, and it can detect the theory with that param type (Browser), it's cool.

Don't know whether the example should return base; also, but anyway thanks for sharing the idea in form of code example.

santeriv avatar Oct 20 '11 06:10 santeriv

Okay, sounds good. Renaming the feature request.

dsaff avatar Oct 21 '11 19:10 dsaff

thanks.

santeriv avatar Oct 25 '11 09:10 santeriv

Is this issue still valid for JUnit 4, since there was created a similar issue in another project?

adrianosimoes avatar Feb 27 '17 22:02 adrianosimoes

I'm not convinced there is a great need for some kind of an before method for theory values. The initial code could be written as:

@Datapoints
public BrowserWrapper[] getWrappedBrowsers() { ... }

@Theory
public void theoryBrowse(BrowserWrapper wraper) {
  Browser browser = wrapper.getBrowser(); // does one-time initialization
  stuff.do();
}

@Theory
public void theoryBrowseMore(BrowserWrapper wraper) {
  Browser browser = wrapper.getBrowser(); // does one-time initialization
  stuff.do();
}

kcooney avatar Feb 28 '17 00:02 kcooney

If we wanted to have first-class support of initialization of data point values, we could do this:

@Datapoints
public Callabe<Browser>[] getBrowsers() { ... }

@Theory
public void theoryBrowse(Browser browser) {
  stuff.do();
}

JUnit would see if there were data points methods for Browser and if there were none it would look for methods that return Callable<Browser> and if it found them would call each callable right before calling the theory.

kcooney avatar Feb 28 '17 15:02 kcooney