IDEA Structural Search - matching code at end of method - java

I'm trying to find methods like this:
#Test
public void testStuff()
{
doStuff();
doOtherStuff();
mockery.assertIsSatisfied();
}
The goal is to remove the mockery.assertIsSatisfied(). I can't just remove all calls to it because sometimes it's in the middle of a method or at the end of a loop, where it seems reasonable. Of course, we're using the JUnit #Rule to invoke this automatically, so it's redundant to have it at the end of every test.
I thought this would be the right template:
#Test
public void $testMethod$() throws Exception
{
$Statements$; // configured this as 1..many
mockery.assertIsSatisfied();
}
This matches about 2 methods out of the 400+ usages of that method. Randomly picking some of the other usages of that method, I see that others should have matched the pattern too. (I can't figure out what is common between the ones which do match. They're both try blocks, but so are some of the ones which don't match.)
So what is the right way to do this?
Edit: I just noticed I had hard-coded a throws Exception onto this one, so I re-executed the search without it, and that gives 0 results. In case anybody is wondering.

It's (currently) not possible to use a naked method as a pattern. To search for a method you need to surround it with a class like this:
class $Class$ {
#Test
public void $testMethod$() // 1..unlimited
{
$Statements$; // 1..unlimited
mockery.assertIsSatisfied();
}
}
Be sure that the method is also configured with occurrences 1..unlimited, or only one method per class will be found.

Related

How to keep the code dry while using a function in selenium with testng?

Let's assume that I have a method that when called makes a screenshot of the page and saves it in a folder. I want to know a better way of using the method without repeating myself because right now is working like this (I am using selenium-webdriver with testng and java):
public class TestClass{
#Test
public void firstTest(){
step1();
step2();
takeScreenshot();
step3();
takeScreenshot();
step4();
takeScreenshot();
step5();
step6();
takeScreenshot();
}
#Test
public void secondTest(){
step1();
step2();
takeScreenshot();
step3();
takeScreenshot();
step4();
step5();
step6();
takeScreenshot();
}
}
As you can see, right now I call the method after any step in the test methods when I need to capture a screenshot but it doesn't look too clean. So I am wondering if it is a better way to do this.
I don't know what are the steps do. But if those are the assertions then you could just split them in separate tests and call the screenshot method in the #AfterTest method. That way after every test screenshot will be taken and you don't have to repeat the screenshot method call.
My first thought is that what you have right now is not too bad. It's simple, explicit, and easily configurable (i.e. step4() has a screenshot in the first test, but not the second). You want to abstract away the screenshots because they feel like clutter, but you're making a decision as the author to call it in some situations and not others, and that decision has to be encoded somewhere.
That said, you could...
A) Bury takeScreenshot() down in the step() functions, and pass in a flag that triggers it when true. However, using flags like this violates the Do One Thing principle, which makes Uncle Bob grumpy.
public void secondTest(){
step1();
step2(true);
step3(true);
step4();
step5();
step6(true);
}
B) You could do something REALLY fancy and make all of your step() functions return this, so you can chain them with takeScreenshot() (which I assume is elsewhere in TestClass). That would allow you to commit this (probably terrible) crime:
public void secondTest(){
step1();
step2().takeScreenshot();
step3().takeScreenshot();
step4();
step5();
step6().takeScreenshot();
}
C) Sacrifice the ability to configure whether or not the screenshot is taken after a given action, and just hardcode it into the set of actions you care most about.
D) Or my favorite option, leave it as is. Just because you're calling a function over and over doesn't mean your code isn't DRY. You're not duplicating any real logic. It's more lines of code, but hey, you're not going to run out of lines. Ditching cruft and syntax can make your code more readable, but if you squeeze it too much, trying to do 20 things in 12 lines, it can backfire. Treat yourself to those extra lines of code, it's the weekend, you deserve it.
I advice you to go like this: make each "step" method into a test. Then, use TestNG annotations of #BeforeTest or #AfterTest like this:
#Test
public void Step1()
{
// write here step1 code...
}
#Test
public void Step2()
{
// write here step2 code...
}
#AfterTest
public void takeScreenshot()
{
// takeScreenshot method code goes here
}
This way the takeScreenshot method will run after each step and you will get a cleaner a better code.

Verifying a call of a static void method with powermockito

I am trying to capture the 'logError' method in a static class (in the sense of every method/field is static), and verify it has been called some number of times by other methods in the same class.
this method is:
public static void logError(Object message){
LOGGER.error(message); // static logger
}
my attempt to test it:
#Test
public void errLogTest() throws Exception{
PowerMockito.mockStatic(X.class);
PowerMockito.doNothing().when(X.class);
X.logError(Mockito.anyString());
X.open();
X.open(); //should log error for opening twice
PowerMockito.verifyStatic(Mockito.times(1));
}
My problem is, no matter how many times I specify, it passes. I removed mocking behavior and know for a fact the logger is called once, but I can have PowerMockito.verifyStatic(Mockito.times(9001)); instead and it still passes. How do I test this?
You're missing a line of code after verifyStatic. You're not telling PowerMock what to verify. You're also mocking all static methods of the class instead of just the one you don't want called.
#Test
public void errLogTest() throws Exception{
PowerMockito.spy(X.class); //Used to be: PowerMockito.mockStatic(X.class);
PowerMockito.doNothing().when(X.class);
X.logError(Mockito.anyString());
X.open();
X.open(); //should log error for opening twice
PowerMockito.verifyStatic(Mockito.times(1));
X.logError(Mockito.anyString()); //Now verifyStatic knows what to verify.
}
You may still need to do some debugging because, in my experience, setting up the expectations sometimes calls the underlying method anyway.
Here's the javadoc for spy: http://static.javadoc.io/org.powermock/powermock-api-mockito/1.5.4/org/powermock/api/mockito/PowerMockito.html#spy(java.lang.Class)
Here's the javadoc for verifyStatic: http://static.javadoc.io/org.powermock/powermock-api-mockito/1.5.4/org/powermock/api/mockito/PowerMockito.html#verifyStatic(org.mockito.verification.VerificationMode)

Mocking a Spy method with Mockito

I am writing a unit test for a FizzConfigurator class that looks like:
public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
// Does a bunch of stuff and hits a database.
}
}
I'd like to write a simple unit test that stubs the doWidget(String,Config) method (so that it doesn't actually fire and hit the database), but that allows me to verify that calling doBuzz(String) ends up executing doWidget. Mockito seems like the right tool for the job here.
public class FizzConfiguratorTest {
#Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
// We should never get here. Calling doBuzz should invoke our
// stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; // Test passed.
}
}
}
This seems like a good gameplan (to me at least). But when I actually go to code it up, I get the following compiler error on the 2nd line inside the test method (the Mockito.when(...) line:
The method when(T) in the type Mockito is not applicable for the arguments (void)
I see that Mockito can't mock a method that returns void. So I ask:
Am I approaching this test setup correctly? Or is there a better, Mockito-recommended, way of testing that doBuzz calls doWidget under the hood? And
What can I do about mocking/stubbing doWidget as it is the most critical method of my entire FizzConfigurator class?
I wouldn't use exceptions to test that, but verifications. And another problem is that you can't use when() with methods returning void.
Here's how I would do it:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
This isn't a direct answer to the question, but I ran across it when trying to troubleshoot my problem and haven't since found a more relevant question.
If you're trying to stub/mock an object marked as Spy, Mockito only picks up the stubs if they're created using the do...when convention as hinted at by JB Nizet:
doReturn(Set.of(...)).when(mySpy).getSomething(...);
It wasn't being picked up by:
when(mySpy.getSomething(...)).thenReturn(Set.of(...));
Which matches the comment in MockHandlerImpl::handle:
// stubbing voids with doThrow() or doAnswer() style
This is a clear sign that doWidget method should belong to another class which FizzConfigurator would depend on.
In your test, this new dependency would be a mock, and you could easily verify if its method was called with verify.
In my case, for the method I was trying to stub, I was passing in incorrect matchers.
My method signature (for the super class method I was trying to stub): String, Object.
I was passing in:
myMethod("string", Mockito.nullable(ClassType.class)) and getting:
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
When using a matcher in another parameter, we also need to use one for the string:
myMethod(eq("string"), Mockito.nullable(ClassType.class))
Hope this helps!

Selenium, minimizing repetitious code

The selenium tests I'm gonna be doing are basically based on three main steps, with different parameters. These parameters are passed in from a text file to the test. this allows easy completion of a test such as create three of "X" without writing the code to do the create three times in one test.
Imagine i have a test involving creating two of "X" and one of "Y". CreateX and CreateY are already defined in separate tests. Is there a nice way of calling the code contained in createX and createY from say, Test1?
I tried creating a class with the creates as seperate methods, but got errors on all the selenium.-anything-, ie every damn line. it goes away if i extend seleneseTestCase, but it seems that my other test classes wont import from a class that extends seleneseTestCase. I'm probably doing something idiotic but i might as well ask!
EDIT:
well for example, its gonna be the same setUp method for every test, so id like to only write that once... instead of a few hundred times...
public void ready() throws Exception
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "https://localhost:9443/");
selenium.start();
selenium.setSpeed("1000");
selenium.setTimeout("999999");
selenium.windowMaximize();
}
thats gonna be used EVERYWHERE.
its in a class called reuseable. Id like to just call reuseable.ready(); from the tests SetUp... but it wont let me....
public class ExampleTest {
#Before
public void setup() {
System.out.println("setup");
}
public void someSharedFunction() {
System.out.println("shared function");
}
#Test
public void test1() {
System.out.println("test1");
someSharedFunction();
}
#Test
public void test2() {
System.out.println("test2");
someSharedFunction();
}
}
The contents of the function after the #Before annotation is what will be executed before every test. someSharedFunction() is an example of a 'reusable' function. The code above will output the following:
setup
test1
shared function
setup
test2
shared function
I would recommend using JUnit and trying out some of the tutorials on junit.org. The problem you have described can be fixed using the #Before annotation on a method that performs this setup in a super class of your tests

How do you customize exception handling behavior in JUnit 3?

I want to implement exception checking (like in JUnit 4) using JUnit 3. For example, I would like to be able to write tests like this:
public void testMyExceptionThrown() throws Exception {
shouldThrow(MyException.class);
doSomethingThatMightThrowMyException();
}
This should succeed if and only if a MyException is thrown.
There is the ExceptionTestCase class in JUnit, but but I want something that each test* method can decide to use or not use. What is the best way to achieve this?
Would the solution:
public void testMyExceptionThrown() throws Exception {
try {
doSomethingThatMightThrowMyException();
fail("Expected Exception MyException");
} catch(MyException e) {
// do nothing, it's OK
}
}
be suitable for what you're thinking of?
Also have a look at this thread, where someone created a Proxy-solution for JUnit3 which seems to be another possibility to solve your problem.
There is no need to implement your own solution because there is already one that can be used with JUnit3 (and any other testing framework): catch-exception.
The simplest approach is to use the Execute Around idiom to abstract away the try-catch that you would usually write.
More sophisticated is to note that TestCase is just a Test. I forget the details, but we can override the execution of the test (which the framework initially calls through run(TestResult) specified in Test). In that override we can place the try-catch, as per Execute Around. The testXxx method should call a set method to install the expected exception type.

Categories

Resources