I have a class-under-test that has the following code :
public void getDetails (String message){
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
StringReader strReader = new StringReader(message);
InputSource inputSrc = new InputSource(strReader);
Document doc = docBuilder.parse(inputSrc);
...
}
I want to write a JUnit for this piece of code using Mockito.
I tried various things like :
DocumentBuilderFactory docBuilderFactoryMock = Mockito.mock(DocumentBuilderFactory.class);
Mockito.when(DocumentBuilderFactory.newInstance()).thenReturn(docBuilderFactoryMock);
But I get the Exception:
org.mockito.exceptions.misusing.WrongTypeOfReturnValue:
DocumentBuilderFactory$$EnhancerByMockitoWithCGLIB$$23223735 cannot be returned by toString()
toString() should return String
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. This exception *might* occur in wrongly written multi-threaded tests.
Please refer to Mockito FAQ on limitations of concurrency testing.
2. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
If I do the following:
DocumentBuilderFactory docBuilderFactoryMock = Mockito.spy(DocumentBuilderFactory.newInstance());
DocumentBuilder documentBuilderMock = Mockito.mock(DocumentBuilder.class);
Mockito.when(docBuilderFactory.newDocumentBuilder()).thenReturn(documentBuilderMock);
docBuilderdocBuilderMockito.when(docBuilderFactoryMock.newDocumentBuilder()).thenReturn(docBuilderFactoryMock);
and debug my code then I see that the class-under-test does not use my Mock objects anywhere but creates its own objects and throws a SAXParseException at
Document doc = docBuilder.parse(inputSrc);
Unit testing is intended to test your components/classes, not the library components/classes that are used.
Your class is parsing a String as xml content and to test that, you will find that providing a set of xml Strings with known output is the best way to test.
Simply pass a known xml String to your class under test and assert that the resulting model that is parsed, contains the data that you expect for that xml content.
I don't think that you need any mocking.
Related
For my JUnit Tests with Mockito, I am doing the following:
Mockito.lenient().when(tokenService.create(String id, Any)).thenReturn(new String (id))
Mockito.lenient().when(voucherRepo.findById(id String).thenReturn(new Voucher(id));
I would like to access the String id given to tokenService.create() and voucherRepo.findById() methods, create and then return mock objects using it. How it can be done?
Mockito.when(voucherRepo.findById(id)).thenReturn(new Voucher(id));
Your solution should work and is probably the preferred solution for any clear defined test.
As you know in your test what the exact id is, you can just return the specific object for it.
Another way to do this - for arbitrary strings - is using mockito's thenAnswer funtionality:
Mockito.when(voucherRepo.findById(Mockito.any(String.class))).thenAnswer(new Answer<Voucher>() {
#Override
public Voucher answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String id = (String) args[0];
return new Voucher(id);
}
});
I am not sure what reason you have to do that in your test (as this a rather arbitrary defintion), but in doubt consider adding some more context to your question.
What can possible go wrong with this:
public void Main()
{
var input = new StringReader(Document);
var deserializer = new Deserializer(namingConvention: new CamelCaseNamingConvention());
var p = deserializer.Deserialize<Person>(input);
Console.WriteLine(p.Name);
}
public class Person
{
public string Name {get;set;}
}
private const string Document = #"Name: Peter";
A serialization exception is thrown:
Property 'Name' not found on type 'YamlDotNet.Samples.DeserializeObjectGraph+Person'
The same happens if I first serialize a Person object using the Serializer.
While the online sample for deserialization works just fine - this trivial code does not. What am I missing? It must be a stupid little detail. (But it happened before with other data structures I tried.)
As it seems, the problem is with the namingConvention parameter. If I don't set it to an instance of CamelCaseNamingConvention all is fine.
Unfortunately the "canonical" example (https://dotnetfiddle.net/HD2JXM) uses it and thus suggests it is important.
For any reason the CamelCaseNamingConvention converts the fields to lowercase in the class (ie. 'Name' to 'name'). As the string is 'Name' and not 'name' the deserialization fails. The example uses lower-case therefore it works....
I had the same problem....
Inside my ATG Droplet, I am fetching records from repository. Now when I try to mock RQLStatement it throws a org.mockito.exceptions.misusing.MissingMethodInvocationException
Below are the statements I am trying to mock:
final RepositoryView view = this.getRepository().getView("product");
final RqlStatement statement = RqlStatement.parseRqlStatement("id = ?0");
prodItems = statement.executeQuery(view, params);
I used mockito and powermockito but its not working
PowerMockito.mockStatic(RqlStatement.class);
PowerMockito.when(RqlStatement.parseRqlStatement("id =?0")).thenReturn(this.statementmock);
Mockito.when(this.statementmock.executeQuery(this.viewMock, params)).thenReturn(new RepositoryItem[4]);
Adding #PrepareForTest annotation .working for me now
I have a bit of a complex program which is giving me this apparently phantom error...
I'll start explaining with the help of this little example program I rigged that can throw my beautiful exception for anyone who runs it.
<!-- language: c# -->
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace so_redux {
static class Program {
[STAThread]
static void Main(){
CS2JS _class=new CS2JS();
}
}//class Program
class CS2JS{
public CS2JS(){
Func<String,Object> js_eval=initJS();
Object cs_ic=initCS();
string xc;
object res;
cs_ic.GetType().GetMethod("init").Invoke(cs_ic,null);
AppDomain.CurrentDomain.SetData("trespasser",cs_ic);
xc=#"function edata(fieldname:String,ival:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var v1=sob.GetType().GetField(fieldname).GetValue(sob);
function HASH(s1:String,s2:String):Object{
var q1=sob.GetType().GetField(s1).GetValue(sob);
return q1.ITEM(s2);
}
var v2=v1.ITEM(ival);
return eval(v2);
}
edata('HT','foo');";
res=js_eval(xc);
// var xx;xx=new Hashtable();xx['sda']='1';eval(xx['sda']); OK
}
Func<String,Object> initJS(){
System.CodeDom.Compiler.CodeDomProvider jcc;
System.CodeDom.Compiler.CompilerParameters jcp;
System.CodeDom.Compiler.CompilerResults jcr;
System.Reflection.Assembly jas;
object jis;
string code;
Type t_ii;
code=#"#set #debug(off)
import System;
import System.Collections;
import System.Collections.Generic;
package internal_namespace{class internal_class{
public function internal_method(_code:String):Object{
return eval(_code);
}
}
}";
jcc=Microsoft.JScript.JScriptCodeProvider.CreateProvider("JScript");
jcp=new System.CodeDom.Compiler.CompilerParameters();
jcp.CompilerOptions="/fast-";
jcp.GenerateExecutable=false;
jcp.GenerateInMemory=true;
jcp.IncludeDebugInformation=false;
jcp.ReferencedAssemblies.Add("System.dll");
jcp.ReferencedAssemblies.Add("System.Core.dll");
jcp.WarningLevel=4;
jcr=jcc.CompileAssemblyFromSource(jcp,code);
jas=jcr.CompiledAssembly;
jis=jas.CreateInstance("internal_namespace.internal_class");
t_ii=jas.GetType("internal_namespace.internal_class");
return (s1)=>t_ii.InvokeMember("internal_method",System.Reflection.BindingFlags.InvokeMethod,null,jis,new object[]{s1});
}//initJS
Object initCS(){
var v1= Microsoft.CSharp.CSharpCodeProvider.CreateProvider("CSharp");
System.CodeDom.Compiler.CompilerParameters v2=new System.CodeDom.Compiler.CompilerParameters();
v2.GenerateExecutable=false;
v2.GenerateInMemory=true;
v2.IncludeDebugInformation=false;
v2.WarningLevel=4;
v2.ReferencedAssemblies.Add("System.dll");
v2.ReferencedAssemblies.Add("System.Core.dll");
string _code="public Hashtable2 HT;"+
"public void init(){"+
"HT=new Hashtable2();"+
"HT[\"foo\"]=\"1\";"+
"HT[\"bar\"]=\"HASH('HT','foo')\";"+
"}";
var v3="using System;using System.Collections;using System.Collections.Generic;"+
"namespace internal_namespace{public class Hashtable2:Hashtable{"+
"public Hashtable2():base(){} public Hashtable2(int N):base(N){}"+
"public Object ITEM(Object K){return this[K];} }"+
"[Serializable]public class internal_class{"+
"public internal_class(){}"+
_code+
"\n}}";
var v4=v1.CompileAssemblyFromSource(v2,v3);
var v5=v4.CompiledAssembly;
var v6=v5.GetType("internal_namespace.internal_class");
var v7=v5.CreateInstance("internal_namespace.internal_class");
return v7;
}//initCS
}//class CS2JS
}//namespace so_redux
The exception that is thrown is "index out of bounds", and it's thrown from JScript. The problem? It's that there is no array!
What this code is doing: first a JScript interpreter is initialized by compiling at runtime a class that "exports" an eval (one could do a dll, but in this case I didn't).
Then a C# assembly is compiled, an assembly that "exports" some user code (the variable _code in initCS is originally loaded by reading a text file).
After the initialization of the newly compiled class (the invoking of init()), I need the two assemblies (JScript and C#) to interact, so I need to pass data between them, and I thought of using AppDomain.
Note: in the C# assembly an Hashtable2 is defined because I put in there an ITEM method that one can use in alternative to the common property this[]: in this way debugging is easier (for examply by showing a holy MessageBox when accessing the values).
So, I pass the class instantiated in initCS to JScript, and JScript reads the internal Hashtable (HT). What I need to do is evaluate the data in the Hashtable, because it is supposed to be able to alter itself dynamically.
Everything works fine if I eval a string not taken from the Hashtable -- in the moment I take whatever is in the Hashtable and pass it to eval, then exceptions happen. Attention: the strings are absolutely the same (even comparing them with Equals) and they work, the difference is only from where they come from.
When the JScript function edata evals a string taken from the Hashtable, JScript says "index out of bounds", but as I was saying: I don't see any array there... (and maybe the problem is exactly that, dunno).
I admit I have my limitations in JScript, so if anybody could lend a hand to help understand WTF is going on, I would be really happy.
Temporary solution/workaround splitting the JScript function:
xc=#"function odata(fieldname:String,ival:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var v1=sob.GetType().GetField(fieldname).GetValue(sob);
return v1.ITEM(ival);
}
odata('HT','bar');";
res=js_eval(xc);
xc=#"function HASH(s1:String,s2:String):Object{
var sob=System.AppDomain.CurrentDomain.GetData('trespasser');
var q1=sob.GetType().GetField(s1).GetValue(sob);
return q1.ITEM(s2);
}
eval("+res.ToString()+");";
res=js_eval(xc);
but if anybody really got any idea of why is wrong in the first example, please explain me!
I'm getting into TDD; using nUnit and RhinoMocks 3.5.
I'm trying to figure out how to AssertWasCalled on a method in the SystemUnderTest (SUT). My understanding is that you can't mock the system under test. In fact, my current test results in an exception because the I'm using the AssertWasCalled on the SUT.
OrdersPresenter:
public void OnViewLoad_GetOrders()
{
var orders = GetOrders();
View.Model.Orders = orders;
}
public List<Orders> GetOrders()
{
return _ordersRepository.GetAll();
}
OrdersPresenterTest:
_ordersPresenter = new OrdersPresenter(_view, _ordersRepository);
[Test]
public void OnViewLoad_GetOrders_Should_Call_GetOrders()
{
_view.Raise(v => v.LoadOrders += _ordersPresenter.OnViewLoad_GetOrders, view, new EventArgs);
_ordersPresenter.AssertWasCalled(d => d.GetOrders); // Getting non-mock exception here
}
How do I Assert GetOrders was called in the SUT? I haven't been able to figure it out in the docs.
Any help is greatly appreciated.
Edit:
I understand the GetOrders method in the SUT should be private. I went back thru Roy Osherove's Art of Unit Testing to see how to test private methods. Roy says making a method public (to test against) is not necessarily a bad thing, so I will keep it public.
So I've written a test for GetOrders and I assert the return value ShouldBe a list of orders. That said, I believe I need to restructure my test for OnViewLoad_GetOrders by stubbing the value I get from GetOrders and asserting the results of my actions on that object.
Can someone confirm and explain?
You can not use AssertWasCalled() on not-mocked objects. Just abstract class OrdersPresenter by an interface (use Extract Interface refactoring technique) and then
var ordersPresenter = MockRepository.GenerateMock<IOrderRepository>();
view.Raise(...);
_ordersPresenter.AssertWasCalled(d => d.GetOrders);
BTW,
for me it is not clear why RhinoMocks not used generic parameter constraint for AssertWasCalled
public static void AssertWasCalled<T>(this T mock, Action<T> action,
Action<IMethodOptions<object>> setupConstraints)
Basically T is not limited, but I believe it would be better limit it to somethign like IMockMarkerInterface