How to mock a Consumer argument using EasyMock with PowerMock - powermock

I have a test scenario where I need to mock a Consumer parameter.
In the following code the startTracer is the method to be tested.
class TracerService {
private TracerController tracerController;
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
...
}
Basically, I want to test if the tracerController.startTracer(param1) is receiving the param1 as argument.
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1));
expectLastCall().once();
...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
How I can configure EasyMock/PowerMock for that executeOnTracerControllerScope execute tracerController.startTracer without invocating their internal code?

tracerController is a mock. So startTracer won't be called on it. As defined right now, it will simply do nothing. The code doing what you are asking should be something like that:
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1)); // no need for the expect, it's the default
replay(tracerController);
// ...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
Of course, attendStartConditions and executeOnTracerControllerScope will be called for real.
Following your comment, if you want to mock executeOnTracerControllerScope, you will do the code below. However, your lambda won't be called anymore. So you won't be able to validate the param.
public class MyTest {
#Test
public void test() {
TracerController tracerController = mock(TracerController.class);
TracerService service = partialMockBuilder(TracerService.class)
.withConstructor(tracerController)
.addMockedMethod("executeOnTracerControllerScope")
.mock();
replay(tracerController);
service.startTracer("tracer", "param");
}
}
class TracerService {
private final TracerController tracerController;
public TracerService(TracerController tracerController) {
this.tracerController = tracerController;
}
public boolean attendStartConditions(String tracerName, Object param1) {
return true;
}
public void executeOnTracerControllerScope(Consumer<TracerController> tracer) {
tracer.accept(tracerController);
}
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
}
interface TracerController {
void startTracer(Object param1);
}

Related

mybatis clientGenerated couldn't call back

i code a plugin for mybatis generator, but in clientGenerated of extends plugin method doesn't work.
please helpe me ~ ^_^
code is in under:
public class MapperAnnotationPlugin extends PluginAdapter {
private final static Map<String, String> ANNOTATION_IMPORTS;
static {
ANNOTATION_IMPORTS = new HashMap<>();
ANNOTATION_IMPORTS.put("#Mapper", "org.apache.ibatis.annotations.Mapper");
ANNOTATION_IMPORTS.put("#Repository", "org.springframework.stereotype.Repository");
}
private List<String> annotationList;
#Override
public void initialized(IntrospectedTable introspectedTable) {
super.initialized(introspectedTable);
this.annotationList = new ArrayList<>();
Properties properties = this.getProperties();
boolean findMapper = false;
for (Object key : properties.keySet()) {
String keyStr = key.toString().trim();
if (keyStr.startsWith("#Mapper")) {
findMapper = true;
}
if (StringUtility.isTrue(properties.getProperty(key.toString()))) {
annotationList.add(keyStr);
}
}
if (!findMapper) {
annotationList.add(0, "#Mapper");
}
}
#Override
public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
super.clientGenerated(interfaze, introspectedTable);
for (String annotation : annotationList) {
if ("#Mapper".equals(annotation)) {
if (introspectedTable.getTargetRuntime() == IntrospectedTable.TargetRuntime.MYBATIS3) {
interfaze.addImportedType(new FullyQualifiedJavaType(ANNOTATION_IMPORTS.get(annotation)));
interfaze.addAnnotation(annotation);
}
} else if (Objects.nonNull(ANNOTATION_IMPORTS.get(annotation))) {
logger.info(PluginConst.TEACHEE_PLUGIN + "添加" + annotation);
interfaze.addImportedType(new FullyQualifiedJavaType(ANNOTATION_IMPORTS.get(annotation)));
interfaze.addAnnotation(annotation);
}
}
return true;
}
}
in second method, in debug, it had not go this method, so what could i do in next step
Same problem when I maked a plugin for mybatis-generator-plugin. The method of clientGenerated didnot be callback. It is my way, call from another method which include Interface object.
#Override
public boolean clientCountByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
this.clientGenerated(interfaze, null, introspectedTable);
return false;
}
Both generator-core/generator-plugin version is 1.4.0, work fine now.
https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.4.0

How to run different tests on a single Document variable which was fetched with Jsoup.connect(string)

I have multiple test cases and I want to use a single Document variable with all of them.
There are more test units which will use this Document.
I had an idea to download the html code, in order to avoid connecting to the site multiple times and taking up server resources, but still I think that it wouldn't be an optional approach to testing.
public class ScrapperTest {
public ScrapperTest() {
}
#BeforeClass
public static void setUpClass() {
}
#AfterClass
public static void tearDownClass() {
}
#Before
public void setUp() {
}
#After
public void tearDown() {
}
/**
* Test of scrapeManufacturer method, of class Scrapper.
*/
#Test
public void testScrapeManufacturer() {
System.out.println("scrapeManufacturer");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeManufacturer(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
}
/**
* Test of scrapeMinPrice method, of class Scrapper.
*/
#Test
public void testScrapeMinPrice() {
System.out.println("scrapeMinPrice");
Document html = null;
Scrapper instance = new ScrapperImpl();
String expResult = "";
String result = instance.scrapeMinPrice(html);
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}

junit for multi threaded class with mockito

Please, help me write a JUnit test for this code using Mockito.
class A{
private BlockingQueue<Runnable> jobQueue;
public void methodA(List<String> messages) {
try {
jobQueue.put(() -> methodB(message));
} catch(InterruptedException e) {}
}
private void methodB(Message message) {
//other logic
}
}
Your example lacks context as to what it is methodB is doing... Without knowing what the functionality is that you want to verify, just verifying that methodB gets called wouldn't be a particularly useful test, nor is mocking the BlockingQueue. I'm going to go out on a limb and assume that methodB interacts with another object, and it's this interaction that you really want to verify, if that's the case my code and test would look something like:
class A {
private BlockingQueue<Runnable> jobQueue;
private B b;
public void methodA(Message message) {
try {
jobQueue.put(() -> methodB(message));
} catch (InterruptedException e) {
}
}
private void methodB(Message message) {
b.sendMethod(message);
}
}
class B {
public void sendMethod(Message message) {
// other logic
}
}
And my test would potentially look something like:
class Atest {
private A testSubject;
#Mock
private B b;
#Test
public void testASendsMessage() {
Message message = new Message("HELLO WORLD");
testSubject.methodA(message);
verify(b, timeout(100)).sendMethod(message);
}
#Before
public void setup() throws Exception {
testSubject = new A();
}
}
In general you want to avoid needing to verifying bits with multiple threads in a unit test, save tests with multiple running threads mainly for integration tests but where it is necessary look at Mockito.timeout(), see example above for how to use. Hopefully this helps?

Junit testing for a class with strings

//DOC Datatype Constants
public enum DocDatatype {
PROFILE("Profile"),
SUPPORT_DETAIL("SupportDetail"),
MISC_PAGE("MiscPage"),
String name;
DocDatatype(String name) {
this.name = name;
}
public String getName() {
return name;
}
// the identifierMethod
public String toString() {
return name;
}
// the valueOfMethod
public static DocDatatype fromString(String value) {
for (DocDatatype type : DocDatatype.values()) {
if (type.getName().equals(value))
return type;
}
throw new java.lang.IllegalArgumentException(value
+ " is Not valid dmDataType");
}
}
I have written the junit test case in this way. Whether it is right way to write or wrong way...?
public class DocDatatypeTest {
private static final Log logger = LogFactory
.getLog(TreeConstantTest.class);
#Test
public void testDocDatatypeFromName()
{
DocDatatype d= DocDatatype.fromString("Profile");
assertTrue((d.toString().compareToIgnoreCase("PROFILE") == 0));
}
#Test
public void testDocDatatypeFromName1()
{
DocDatatype d = DocDatatype.fromString("SupportDetail");
assertTrue((d.toString().compareToIgnoreCase("SUPPORT_DETAIL") == 0 ));
}
}
}
A few things here:
Remove the logger from the test. A test should pass or fail, no need for logging
Don't use assertTrue for this. If the test fails it will give you no information about /why/ it failed.
I would change this to
#Test
public void testDocDatatypeFromName()
{
DocDatatype actualDocType = DocDatatype.fromString("Profile");
assertSame(DocDataType.PROFILE, actualDocType);
}
If you really want to assert that value of the toString then do this
#Test
public void testDocDatatypeFromName()
{
DocDatatype d= DocDatatype.fromString("Profile");
assertEquals("Profile", d.toString());
}
You're missing tests for when the lookup doesn't match anything
I wouldn't even write these tests as I see them adding no value whatsoever. The code that uses the enums should have the tests, not these.
Your tests are named very badly. There's no need to start a test with test and the fact you add a "1" to the end of the second test should tell you something. Test names should focus on action and behaviour. If you want to read more about this, get the December issue of JAX Magazine which has a snippet about naming from my forthcoming book about testing.

Ninject Load FromAssembliesInPath with a Constructor

if i say have code that works like this:
private static void LoadFromAssemblies(IKernel kernel)
{
string appPath = HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath);
kernel.Scan(a =>
{
a.FromAssembliesInPath(string.Format(#"{0}\Extensions", appPath));
a.AutoLoadModules();
a.BindWithDefaultConventions();
a.InRequestScope();
});
}
and just assume that each class defined in the target assembly has a string argument in the constructor, how would i go about passing in the string argument from the code above?
Do i instead use an Interceptor?
Thanks in advance, John
In my project into some repositories I pass ISession (nHibernate) and to others connectionString for DataContext(Linq2SQL)
To pass the connection string I have created LinqConfiguration class
public class LinqConfiguration : ILinqConfiguration
{
private readonly string _connectionString;
public LinqConfiguration(string connectionString)
{
_connectionString = connectionString;
}
public string GetConnectionString()
{
return _connectionString;
}
}
My repository looks like this:
public class WebClientRepository : IWebClientRepository
{
private readonly WebClientDataClassesDataContext datacontext;
private ILinqConfiguration _linqconfig;
public WebClientRepository(ILinqConfiguration linqconfig)
{
_linqconfig = linqconfig;
datacontext = new WebClientDataClassesDataContext(_linqconfig.GetConnectionString());
}
//....
}
and binding using Conventions:
public class LinqRepositoryModule: NinjectModule
{
public override void Load()
{
Bind<ILinqConfiguration>()
.To<LinqConfiguration>()
.WithConstructorArgument("connectionString",
ConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString
);
IKernel ninjectKernel = this.Kernel;
ninjectKernel.Scan(kernel =>
{
kernel.FromAssemblyContaining<IWebClientRepository>();
kernel.FromAssemblyContaining<WebClientRepository>();
kernel.Where(t => t != typeof(LinqConfiguration)); // interface is in the same assembly and it is already binded
kernel.BindWithDefaultConventions();
kernel.AutoLoadModules();
kernel.InRequestScope();
});
}
}