I want to verify that a collection contains at least one non-null element. I have tried is(not(empty())), however this passes in the test below.
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.not;
public class SandBoxTest {
#Test
public void shouldTestThis() {
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);
assertThat(collection, is(not(empty())));
}
}
Is there an elegant/simple way to do this?
Things That Don't Work
#Test
public void should(){
Collection<String> collection = new ArrayList();
collection.add("gfas");
collection.add("asda");
assertThat(collection, contains(notNullValue()));
}
java.lang.AssertionError:
Expected: iterable containing [not null]
but: Not matched: "asda"
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
...
assertThat(collection, hasItem(notNullValue(Integer.class)));
Unfortunately, there is a bug in Java 1.6 that means you might have to split it onto 2 lines as described here if you are using 1.6:
Matcher<Iterable<? super String>> matcher = hasItem(notNullValue(Integer.class));
assertThat(collection, matcher);
EDIT Here is the FEST Assert example you asked for:
import static org.fest.assertions.api.Assertions.assertThat;
...
assertThat(collection).doesNotContainNull();
FEST requires only a single static import so you get full IDE auto completion.
I just ran into the same problem and solved it as follows.
The basic idea is that if the collection has only null elements, converted to a set it will contain just one element and it will be null. If not so, then the collection contains at least one non-null element.
I wrote a matcher, and tried it with this test:
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import static personal.CollectionOfNullsMatcher.collectionOfNulls;
public class SimpleTest {
#Test
public void should_check_collection_for_non_null_values() {
Collection<String> testedCollection = new ArrayList<String>();
testedCollection.add(null);
assertThat(testedCollection, is(collectionOfNulls()));
testedCollection.add("any");
assertThat(testedCollection, is(not(collectionOfNulls())));
}
}
class CollectionOfNullsMatcher extends TypeSafeMatcher<Collection> {
#Override
protected boolean matchesSafely(final Collection collection) {
Set<Object> set = new HashSet<Object>(collection);
return (set.size() == 1) && (set.toArray()[0] == null);
}
#Override
public void describeTo(final Description description) {
description.appendText("collection of nulls");
}
#Factory
public static <T> Matcher<Collection> collectionOfNulls() {
return new CollectionOfNullsMatcher();
}
}
Of course, in a real project, the matcher should be placed together with its brothers :)
Hope it helps.
You can try the following:
public void shouldTestThis() {
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);
collection.removeAll(Collections.singleton(null)); // remove all "null" elements from collection
assertThat(collection, is(not(empty())));
}
As ajb notices, if you want to left your array unmodified, you should use an iterator and check each element until the end of the collection or a non null one.
You're on the right track, chaining Matcher instances. You just need the hasItem matcher (like I've suggested here) instead of contains.
Creates a matcher for Iterables that only matches when a single pass
over the examined Iterable yields at least one item that is matched by
the specified itemMatcher. Whilst matching, the traversal of the
examined Iterable will stop as soon as a matching item is found.
For example,
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);
assertThat(collection, hasItem(is(not(nullValue()))));
will fail with
java.lang.AssertionError:
Expected: a collection containing is not null
but: was null
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at com.example.ExampleTest.should(ExampleTest.java:21)
at [...]
whereas
Collection<Integer> collection = new ArrayList<Integer>();
collection.add(null);
collection.add("hey");
collection.add(null);
assertThat(collection, hasItem(is(not(nullValue()))));
// or shortened
assertThat(collection, hasItem(notNullValue()));
will succeed.
Related
I am working on Behaviour Driven Development test - BDD test, for that i am using Cucumber with Gherkin.
In my test function i need to declare a matrix, so in the Given step i declared a table and in the function test i need to give it as a DATATABLE.
To transfer the dataTable elements to int and work with it as a matrix, i used a MAP, but the problem is when i use : List<Map<String,String>> rows = table.asMaps(String.class, String.class);
intellij makes asMaps in red and it shows the problem is : Cannot resolve method 'asMaps' in 'DataTable'
I didn't find a solution for that in google i will attach the code:
package EXO1.com;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import gherkin.ast.DataTable;
import java.util.List;
import java.util.Map;
public class DetStep {
#Given("I have a matrix")
public void iHaveAMatrix(DataTable table) {
List<Map<String,String>> rows = table.asMaps(String.class, String.class);
}
#When("I call function determinant\\(Matrix matrix)")
public void iCallFunctionDeterminantMatrixMatrix() {
}
#Then("I expect the result {int}")
public void iExpectTheResult(int arg0) {
}
}
For the feature class is :
Feature: Calcul Determinant
Scenario: determinant d'une matrice
Given I have a matrix
|col1|col2|col3|
|1|2|0|
|3|1|1|
|2|0|1|
When I call function determinant(Matrix matrix)
Then I expect the result -3
Out of the following two test cases in BundleProcessorTest.java, i am getting below exception, although, my first test case passes successfully.
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
-> at bundle.test.BundleProcessorTest.bundlePluginShouldNotBeNull(BundleProcessorTest.java:22)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
Also, this error might show up because you use argument matchers with
methods that cannot be mocked. Following methods cannot be
stubbed/verified: final/private/equals()/hashCode().
at
bundle.test.BundleProcessorTest.bundlePluginCollectionShouldNotBeNull(BundleProcessorTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
Please find below simplified code listing :-
BundlePlugin.java
package bundle;
import java.util.List;
public class BundlePlugin {
private final String pluginName ;
private final List<String> featureContent ;
public BundlePlugin(String pluginName, List<String> featureContent) {
super();
this.pluginName = pluginName;
this.featureContent = featureContent;
}
public String getPluginName() {
return pluginName;
}
public List<String> getFeatureContent() {
return featureContent;
}
}
BundleProcessor.java
package bundle;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class BundleProcessor {
public BundlePlugin getBundlePlugin(String pluginName, Iterator<String> artifactIterator) {
List<String> featureContent = new ArrayList<String>() ;
return new BundlePlugin(pluginName, featureContent);
}
}
BundleProcessorTest.java
package bundle.test;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
import bundle.BundleProcessor;
public class BundleProcessorTest {
BundleProcessor bundleProcessor = new BundleProcessor() ;
#Test
public void bundlePluginShouldNotBeNull() {
Iterator<String> artifactIterator = mock(Iterator.class) ;
bundle.BundlePlugin bundlePlugin = bundleProcessor.getBundlePlugin(anyString(), artifactIterator) ;
assertNotNull( bundlePlugin );
}
#Test
public void bundlePluginContentShouldNotBeNull() {
Iterator<String> artifactIterator = mock(Iterator.class) ;
bundle.BundlePlugin bundlePlugin = bundleProcessor.getBundlePlugin(anyString(), artifactIterator) ;
List<String> featureContent = bundlePlugin.getFeatureContent() ;
assertNotNull( featureContent );
}
}
How to execute this test without problem.
Edit 1:
But if i mark the bundlePluginCollectionShouldNotBeNull test with #Ignore annotation, then first test case passes without any exception.
You are using mockito anyString() while calling the test method, it should be used only for verifying a mock object to ensure a certain method is called with any string parameter inside the test, but not to invoke the test itself. For your test use empty string "" instead to anyString().
Ideally anyString() should not be used outside the mock or verify block. I was facing the same issue.Changing the anyString() to some string ("xyz") value works fine.
Note : Make a note that you might use anyString() to some other methods that leads in failure of some other method. It wasted my one hour to figure it out. My actual test method was getting passes individually but when i was trying to run that in a hole it was getting failed because of the reason that some other test case was using anyString() outside to mock or verify block.
We need to add a text file to the project's src/test/resources/mockito-extensions directory named org.mockito.plugins.MockMaker and add a single line of text:
mock-maker-inline
please refer article https://www.baeldung.com/mockito-final
Simple, Should use #Spy annotation with #InjectMocks annotation.
I used the hadoop apache to create a counting Bloom Filter. However I get a NullPointerException when I am trying to add keys in it. I tried to change the class structure in many ways but still I get the same result.
Here is the code I did:
package package_name;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.hadoop.util.bloom.*;
public class CBF {
public static CountingBloomFilter CBF = new CountingBloomFilter();
public static void countingFilter (ArrayList<byte[]> CBF_Keys) throws IOException{
CBF_Keys= Keys.keyStringArray;
Iterator<byte[]> iter = CBF_Keys.iterator();
while (iter.hasNext()) {
byte[] temp = iter.next();
Key hadoop_key = new Key(temp, 2.0);
CBF.add(hadoop_key);
}
}
}
problem is CBF = new CountingBloomFilter(). We should use CountingBloomFilter(int vectorSize, int nbHash, int hashType) instead here, otherwise the HashFunction will not be constructed in parent class Filter.
I can't seem to figure out what I'm doing wrong here:
This is the method I'm testing:
public List<Mo> filterDuplicatesByName(List<Mo> dbMos) {
List<String> names = Lists.newArrayList();
for(Mo mo : dbMos) {
try {
String name = mo.getName();
if(names.contains(name)) {
dbMos.remove(mo);
} else {
names.add(name);
}
} catch (DataLayerException ex) {
dbMos.remove(mo);
}
}
return dbMos;
}
And this is my test class:
package com.rondavu.wt.service.recommendations;
import com.google.common.collect.Lists;
import com.rondavu.data.api.Mo;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class RecommendationsUtilsTest {
Mockery context = new Mockery();
RecommendationsUtils recommendationsUtils = new RecommendationsUtils();
final Mo mo = context.mock(Mo.class);
#Test
public void testFilterDuplicatesByName_oneMo() throws DataLayerException {
List<Mo> input = Lists.newArrayList(mo);
List<Mo> expected = Lists.newArrayList(mo);
context.checking(new Expectations() {{
oneOf (mo).getName(); will(returnValue("Mo 1"));
}});
List<Mo> actual = recommendationsUtils.filterDuplicatesByName(input);
context.assertIsSatisfied();
assertEquals(expected, actual);
}
}
When I run the test I get this output:
unexpected invocation: mo.getName()
no expectations specified: did you...
- forget to start an expectation with a cardinality clause?
- call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!
[stack trace]
I'm pretty new to jMock, and Java is not my strongest language in general but I thought that my oneOf (mo).getName() would make it expect that invocation. What am I doing wrong here?
Though it's not clear why at this point, it seems like Mockery is checking a different instance of mo compared to the one you're defining the expectations to. Try inserting context.mock(Mo.class) in the same local scope as the test case (or in an #Before method) and see if that fixes things.
Is all in the title,
I do not understand the problem this time is a bit different, I used the same Object(List) for two different programs and it does not work in the second time, see :
private void jMenuItem23ActionPerformed(java.awt.event.ActionEvent evt) {
init_creer_client();
List items = new ArrayList();
items.add("mawren");
items.add("blabla");
items.add("Bonjour");
CL.show(cartes,"creer_client");
}
screenshot about the error :
by cons here its work smoothly :
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
public class Test_swingx extends JFrame {
public Test_swingx(String title) throws HeadlessException {
this.setTitle(title);
JPanel pan=new JPanel();
JTextField jtf=new JTextField();
jtf.setColumns(20);
List items = new ArrayList();
items.add("hello");
items.add("marwen");
items.add("allooo");
AutoCompleteDecorator.decorate(jtf, items,false);
pan.add(jtf);
this.setContentPane(pan);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setBounds(280, 150, 500, 200);
}
public static void main(String[] args) {
Test_swingx tsx=new Test_swingx("helloo swingx");
}
}
can anyone explain to me ?
You have a java.awt.List import should be java.util.List
It's because the List on the left-hand side is a java.awt.List instead of a java.util.List.
Try changing the line to:
java.util.List items = new ArrayList();
This is probably happening because you're importing java.awt.* and java.util.List. If you can change how you import these classes, you can avoid namespacing the type inline.
Nope, compiles fine:
package cruft;
import java.util.ArrayList;
import java.util.List;
/**
* ListExample description here
* #author Michael
* #link
* #since 2/11/12 7:27 PM
*/
public class ListExample {
public static void main(String[] args) {
List items = new ArrayList();
for (String arg : args) {
items.add(arg);
}
System.out.println(items);
}
}
Runs fine:
"C:\Program Files\Java\jdk1.7.0_02\bin\java" -Didea.launcher.port=7536 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA 111.255\bin" -Dfile.encoding=UTF-8 -classpath . com.intellij.rt.execution.application.AppMain cruft.ListExample foo bar baz bat
[foo, bar, baz, bat]
Process finished with exit code 0
Sanity check: Have you imported both import java.util.List and import java.util.ArrayList?
Check your imports, because java.awt.List is not the same as java.util.List.
I think the confusion comes from having two List types in different packages, as the error message says. You don't give all the code that generates the error, but I think a reasonable start to a fix would be to change the highlighted line to:
java.util.List items = new ArrayList();
and make sure you have imported java.util.*