c# - MOQ returning dynamic types as object issue -
pologise if questions has been asked couldn't find answer anywhere.
my problem when mocking return method using moq method returns dynamic type. i'm using third part library uses dynamic times. moq seems cast dynamic type object.
mock<ifacebookhelper> mockfbhelp = new mock<ifacebookhelper>(); mockfbhelp.setup(x => x.get("me")).returns(new { email = "test@test.com", id="9999" }); method in mocked helper.
public dynamic get(string p) { var client = new facebookclient(accesstoken); return client.get("me"); } code controller using mocked results.
_facebookhelper.accesstoken = accesstoken; dynamic result = _facebookhelper.get("me"); int facebookid = int.parse(result.id); //this errors id doesn't exist. basically moq has returned dynamic type of object require casting something.
does know how around problem? i'm assuming may because moq not coded in .net 4 therefore not support dynamic types?
edit
actually don't think moq issue created own mock class , still had same problem. i'm new dynamic types though not sure what's going on.
edit 2 - part answered.. problem nothing moq after all
actually problem seems due dynamic type being created in different assembly. although got round initial problem using jobject type still want figure out.
namespace mylib.tools { public interface idyntest { dynamic getdata(); } } namespace mylib.tools { public class dyntest : effect.tools.idyntest { public dynamic getdata() { return new { dynamicproperty = "hello" }; } } } namespace warrior.webui.infrastructure { public class usedyntest { private readonly idyntest dyntest; public usedyntest(idyntest dyntest) { this.dyntest = dyntest; } public string rettest() { return dyntest.getdata().dynamicproperty; } } } namespace warrior.tests { [testclass] public class testdyntest { [testmethod] public void testmethod1() { //mock<idyntest> mockdyntest = new mock<idyntest>(); //mockdyntest.setup(x => x.getdata()).returns(new { dynamicproperty = "from unit test" }); dyntestproxy dyntestproxy = new dyntestproxy(); usedyntest usetest = new usedyntest(dyntestproxy); string results = usetest.rettest(); assert.areequal("from unit test", results); } } } namespace warrior.tests { public class dyntestproxy:idyntest { public dynamic getdata() { return (dynamic) new { dynamicproperty = "from unit test" }; } } } there 3 project indicated namespace mylib, warrior.webui , warrior.tests.
test fails error.. 'object' not contain definition 'dynamicproperty' occurs on rettest()
however if move dyntestproxy class warrior.webui project works fine. i'm guessing there problems when sending dynamic types accross different assemblies or something.
i did quick test:
namespace consoleapplication5 { public interface ifacebookhelper { dynamic get(string p); } class program { static void main(string[] args) { mock<ifacebookhelper> mockfbhelp = new mock<ifacebookhelper>(); mockfbhelp.setup(x => x.get("me")).returns(new { email = "test@test.com", id = "9999" }); dynamic result = mockfbhelp.object.get("me"); int facebookid = int.parse(result.id); string email = result.email; } } } this working fine. don't see problem here.
are sure didn't mix things up?
look @ method posted:
public dynamic get(string p) { var client = new facebookclient(accesstoken); return client.get("me"); } maybe should be:
... return client.get(p); ... is _facebookhelper using mock object? should of type ifacebookhelperproxy or during test.
edit:
the problem attempt expose anonymous type across assembly boundaries, since can use anonymous type within assembly created them.
so instead of
public class dyntestproxy:idyntest { public dynamic getdata() { return (dynamic) new { dynamicproperty = "from unit test" }; } } you should use expandoobject:
public class dyntestproxy:idyntest { public dynamic getdata() { dynamic r = new expandoobject(); r.dynamicproperty = "from unit test"; return r; } } or use internalsvisibleto attribute. see here more information. this question may interesting you.
Comments
Post a Comment