Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests #14

Merged
merged 3 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@
<artifactId>mockito-core</artifactId>
<version>4.6.1</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got rid of the mockito error messages by adding an extra dependency as mentioned in the GitHub discussion here.

<version>4.6.1</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/hudson/MockExtensionLists.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import jenkins.model.Jenkins;

/**
* A mocked way to get at {@link ExtensionList}s. In {@code hudson} package due to protected access in {@link ExtensionList}.
* A mocked way to get at {@link ExtensionList}s. In {@code hudson} package due

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love that you added some comments to the class. It's always a good thing to do in order to help people understand what's happening in pieces of code.

* to protected access in {@link ExtensionList}.
*/

public class MockExtensionLists {
Expand All @@ -31,7 +32,7 @@ public ExtensionList<?> getMockExtensionList(HyperLocalPluginManager hlpm, Jenki
doReturn(Collections.emptyIterator()).when(ret).iterator();
return ret;
}
if(extensionLists.get(type.getName()) != null) {
if (extensionLists.get(type.getName()) != null) {
return extensionLists.get(type.getName());
} else {
MockExtensionList<?> mockList = new MockExtensionList<>(hlpm, hudson, type);
Expand All @@ -54,12 +55,12 @@ public MockExtensionList(HyperLocalPluginManager hlpm, Jenkins hudson, Class<T>
private Answer<List<ExtensionComponent<T>>> mockLoad(HyperLocalPluginManager hlpm) {
return new Answer<List<ExtensionComponent<T>>>() {
public List<ExtensionComponent<T>> answer(InvocationOnMock invocation) throws Throwable {
return hlpm.getPluginStrategy().findComponents(mockExtensionList.extensionType, (Hudson)null);
return hlpm.getPluginStrategy().findComponents(mockExtensionList.extensionType, (Hudson) null);
}
};
}

public ExtensionList<T> getMockExtensionList(){
public ExtensionList<T> getMockExtensionList() {
return mockExtensionList;
}
}
Expand Down
99 changes: 51 additions & 48 deletions src/main/java/hudson/MockJenkins.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,62 +35,65 @@
import jenkins.model.Jenkins;

public class MockJenkins {
private MockExtensionLists mockLookup = new MockExtensionLists();
private MockExtensionLists mockLookup = new MockExtensionLists();

/**
* There are a few methods that need to be mocked in order for setup to work properly:
* * getPluginManager -&gt; must return HyperLocalPluginManager
* * getInitLevel -&gt; COMPLETED; Jenkins is "setup" as soon as the pm is populated
* * getExtensionList -&gt; use the MockExtensionLists
* * getPlugin -&gt; get the Plugin information from HyperLocalPluginManager
* There are a few methods that need to be mocked in order for setup to work
* properly:
* * getPluginManager -&gt; must return HyperLocalPluginManager
* * getInitLevel -&gt; COMPLETED; Jenkins is "setup" as soon as the pm is
* populated
* * getExtensionList -&gt; use the MockExtensionLists
* * getPlugin -&gt; get the Plugin information from HyperLocalPluginManager
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public Jenkins getMockJenkins(HyperLocalPluginManager pm) {
Jenkins mockJenkins = mock(Hudson.class); //required by ExtensionList
when(mockJenkins.getPluginManager()).thenReturn(pm);
when(mockJenkins.getInitLevel()).thenReturn(InitMilestone.COMPLETED);
when(mockJenkins.getInstallState()).thenReturn(InstallState.TEST);
when(mockJenkins.getComputers()).thenReturn(new Computer[0]);
when(mockJenkins.getRootDir()).thenReturn(new File(System.getProperty("java.io.tmpdir")));
try {
Field lookup = mockJenkins.getClass().getField("lookup");
lookup.setAccessible(true);
lookup.set(mockJenkins, new Lookup());
Field servletContext = mockJenkins.getClass().getField("servletContext");
servletContext.setAccessible(true);
servletContext.set(mockJenkins, mock(ServletContext.class));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
doAnswer(new Answer<ExtensionList>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
public Jenkins getMockJenkins(HyperLocalPluginManager pm) {
Jenkins mockJenkins = mock(Hudson.class); // required by ExtensionList
when(mockJenkins.getPluginManager()).thenReturn(pm);
when(mockJenkins.getInitLevel()).thenReturn(InitMilestone.COMPLETED);
when(mockJenkins.getInstallState()).thenReturn(InstallState.TEST);
when(mockJenkins.getComputers()).thenReturn(new Computer[0]);
when(mockJenkins.getRootDir()).thenReturn(new File(System.getProperty("java.io.tmpdir")));
try {
Field lookup = mockJenkins.getClass().getField("lookup");
lookup.setAccessible(true);
lookup.set(mockJenkins, new Lookup());
Field servletContext = mockJenkins.getClass().getField("servletContext");
servletContext.setAccessible(true);
servletContext.set(mockJenkins, mock(ServletContext.class));
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
doAnswer(new Answer<ExtensionList>() {
@Override
public ExtensionList answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return mockLookup.getMockExtensionList(pm, mockJenkins, (Class) args[0]);
}
}).when(mockJenkins).getExtensionList(any(Class.class));
}).when(mockJenkins).getExtensionList(any(Class.class));

doAnswer(invocation -> {
Object[] args = invocation.getArguments();
for (Object _d : mockLookup.getMockExtensionList(pm, mockJenkins, Descriptor.class)) {
Descriptor d = (Descriptor) _d;
if (d.clazz == args[0]) {
return d;
}
}
return null;
}).when(mockJenkins).getDescriptor(any(Class.class));
doAnswer(invocation -> {
Object[] args = invocation.getArguments();
for (Object _d : mockLookup.getMockExtensionList(pm, mockJenkins, Descriptor.class)) {
Descriptor d = (Descriptor) _d;
if (d.clazz == args[0]) {
return d;
}
}
return null;
}).when(mockJenkins).getDescriptor(any(Class.class));

doAnswer(new Answer<Plugin>() {
@Override
public Plugin answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
PluginWrapper p = pm.getPlugin((Class) args[0]);
if(p==null) return null; //not actually loaded; might need an override
return p.getPlugin();
}
}).when(mockJenkins).getPlugin(any(Class.class));
doAnswer(new Answer<Plugin>() {
@Override
public Plugin answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
PluginWrapper p = pm.getPlugin((Class) args[0]);
if (p == null)
return null; // not actually loaded; might need an override
return p.getPlugin();
}
}).when(mockJenkins).getPlugin(any(Class.class));

return mockJenkins;
}
}
return mockJenkins;
}
}