You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

serder_test.go 16 kB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. package serder
  2. import (
  3. "fmt"
  4. "reflect"
  5. "testing"
  6. . "github.com/smartystreets/goconvey/convey"
  7. "gitlink.org.cn/cloudream/common/pkgs/types"
  8. "gitlink.org.cn/cloudream/common/utils/reflect2"
  9. )
  10. type FromAnyString struct {
  11. Str string
  12. }
  13. func (a *FromAnyString) FromAny(val any) (bool, error) {
  14. if str, ok := val.(string); ok {
  15. a.Str = "@" + str
  16. return true, nil
  17. }
  18. return false, nil
  19. }
  20. type ToAnyString struct {
  21. Str string
  22. }
  23. func (a *ToAnyString) ToAny(typ reflect.Type) (val any, ok bool, err error) {
  24. if typ == reflect2.TypeOf[map[string]any]() {
  25. return map[string]any{
  26. "str": "@" + a.Str,
  27. }, true, nil
  28. }
  29. return nil, false, nil
  30. }
  31. type FromAnySt struct {
  32. Value string
  33. }
  34. func (a *FromAnySt) FromAny(val any) (bool, error) {
  35. if st, ok := val.(ToAnySt); ok {
  36. a.Value = "From:" + st.Value
  37. return true, nil
  38. }
  39. return false, nil
  40. }
  41. type ToAnySt struct {
  42. Value string
  43. }
  44. func (a *ToAnySt) ToAny(typ reflect.Type) (val any, ok bool, err error) {
  45. if typ == reflect2.TypeOf[FromAnySt]() {
  46. return FromAnySt{
  47. Value: "To:" + a.Value,
  48. }, true, nil
  49. }
  50. return nil, false, nil
  51. }
  52. type DirToAnySt struct {
  53. Value string
  54. }
  55. func (a DirToAnySt) ToAny(typ reflect.Type) (val any, ok bool, err error) {
  56. if typ == reflect2.TypeOf[FromAnySt]() {
  57. return FromAnySt{
  58. Value: "DirTo:" + a.Value,
  59. }, true, nil
  60. }
  61. return nil, false, nil
  62. }
  63. func Test_AnyToAny(t *testing.T) {
  64. Convey("包含用字符串保存的int数据", t, func() {
  65. type Struct struct {
  66. A string `json:"a"`
  67. B int `json:"b"`
  68. C int64 `json:"c,string"`
  69. }
  70. mp := map[string]any{
  71. "a": "a",
  72. "b": 1,
  73. "c": "1234",
  74. }
  75. var st Struct
  76. err := AnyToAny(mp, &st)
  77. So(err, ShouldBeNil)
  78. So(st.A, ShouldEqual, "a")
  79. So(st.B, ShouldEqual, 1)
  80. So(st.C, ShouldEqual, 1234)
  81. })
  82. Convey("只有FromAny", t, func() {
  83. type Struct struct {
  84. Special FromAnyString `json:"str"`
  85. }
  86. mp := map[string]any{
  87. "str": "test",
  88. }
  89. var ret Struct
  90. err := AnyToAny(mp, &ret)
  91. So(err, ShouldBeNil)
  92. So(ret.Special.Str, ShouldEqual, "@test")
  93. })
  94. Convey("字段类型直接实现了FromAny", t, func() {
  95. type Struct struct {
  96. Special *FromAnyString `json:"str"`
  97. }
  98. mp := map[string]any{
  99. "str": "test",
  100. }
  101. var ret Struct
  102. err := AnyToAny(mp, &ret)
  103. So(err, ShouldBeNil)
  104. So(ret.Special.Str, ShouldEqual, "@test")
  105. })
  106. Convey("只有ToAny", t, func() {
  107. st := struct {
  108. Special ToAnyString `json:"str"`
  109. }{
  110. Special: ToAnyString{
  111. Str: "test",
  112. },
  113. }
  114. ret := map[string]any{}
  115. err := AnyToAny(st, &ret)
  116. So(err, ShouldBeNil)
  117. So(ret["str"].(map[string]any)["str"], ShouldEqual, "@test")
  118. })
  119. Convey("优先使用ToAny", t, func() {
  120. st1 := ToAnySt{
  121. Value: "test",
  122. }
  123. st2 := FromAnySt{}
  124. err := AnyToAny(st1, &st2)
  125. So(err, ShouldBeNil)
  126. So(st2.Value, ShouldEqual, "To:test")
  127. })
  128. Convey("使用Convertor", t, func() {
  129. type Struct1 struct {
  130. Value string
  131. }
  132. type Struct2 struct {
  133. Value string
  134. }
  135. st1 := Struct1{
  136. Value: "test",
  137. }
  138. st2 := Struct2{}
  139. err := AnyToAny(st1, &st2, AnyToAnyOption{
  140. Converters: []Converter{func(from reflect.Value, to reflect.Value) (interface{}, error) {
  141. if from.Type() == reflect2.TypeOf[Struct1]() && to.Type() == reflect2.TypeOf[Struct2]() {
  142. s1 := from.Interface().(Struct1)
  143. return Struct2{
  144. Value: "@" + s1.Value,
  145. }, nil
  146. }
  147. return nil, fmt.Errorf("should not arrive here!")
  148. }},
  149. })
  150. So(err, ShouldBeNil)
  151. So(st2.Value, ShouldEqual, "@test")
  152. })
  153. }
  154. func Test_MapToObject(t *testing.T) {
  155. type Base struct {
  156. Int int
  157. Bool bool
  158. String string
  159. Float float32
  160. }
  161. type ArraryStruct struct {
  162. IntArr []int
  163. StArr []Base
  164. ArrArr [][]int
  165. Nil []Base
  166. }
  167. type MapStruct struct {
  168. StrMap map[string]string
  169. StMap map[string]Base
  170. MapMap map[string]map[string]string
  171. Nil map[string]Base
  172. }
  173. type Top struct {
  174. ArrSt ArraryStruct
  175. MapSt *MapStruct
  176. BaseIf any
  177. NilPtr *Base
  178. }
  179. Convey("结构体递归转换成map[string]any", t, func() {
  180. val := Top{
  181. ArrSt: ArraryStruct{
  182. IntArr: []int{1, 2, 3},
  183. StArr: []Base{
  184. {
  185. Int: 1,
  186. Bool: true,
  187. String: "test",
  188. Float: 1,
  189. },
  190. {
  191. Int: 2,
  192. Bool: false,
  193. String: "test2",
  194. Float: 2,
  195. },
  196. },
  197. ArrArr: [][]int{
  198. {1, 2, 3},
  199. {},
  200. nil,
  201. },
  202. Nil: nil,
  203. },
  204. MapSt: &MapStruct{
  205. StrMap: map[string]string{
  206. "a": "1",
  207. "b": "2",
  208. },
  209. StMap: map[string]Base{
  210. "a": {
  211. Int: 1,
  212. Bool: true,
  213. String: "test",
  214. Float: 1,
  215. },
  216. "b": {
  217. Int: 2,
  218. Bool: false,
  219. String: "test2",
  220. Float: 2,
  221. },
  222. },
  223. MapMap: map[string]map[string]string{
  224. "a": {
  225. "a": "1",
  226. "b": "2",
  227. },
  228. "b": nil,
  229. },
  230. Nil: nil,
  231. },
  232. BaseIf: Base{
  233. Int: 1,
  234. Bool: true,
  235. String: "test",
  236. Float: 1,
  237. },
  238. NilPtr: nil,
  239. }
  240. retMp, err := ObjectToMap(val)
  241. So(err, ShouldBeNil)
  242. exceptMap := map[string]any{
  243. "ArrSt": map[string]any{
  244. "IntArr": []any{1, 2, 3},
  245. "StArr": []any{
  246. map[string]any{
  247. "Int": 1,
  248. "Bool": true,
  249. "String": "test",
  250. "Float": 1,
  251. },
  252. map[string]any{
  253. "Int": 2,
  254. "Bool": false,
  255. "String": "test2",
  256. "Float": 2,
  257. },
  258. },
  259. "ArrArr": []any{
  260. []any{1, 2, 3},
  261. []any{},
  262. []int(nil),
  263. },
  264. "Nil": []Base(nil),
  265. },
  266. "MapSt": map[string]any{
  267. "StrMap": map[string]any{
  268. "a": "1",
  269. "b": "2",
  270. },
  271. "StMap": map[string]any{
  272. "a": map[string]any{
  273. "Int": 1,
  274. "Bool": true,
  275. "String": "test",
  276. "Float": 1,
  277. },
  278. "b": map[string]any{
  279. "Int": 2,
  280. "Bool": false,
  281. "String": "test2",
  282. "Float": 2,
  283. },
  284. },
  285. "MapMap": map[string]any{
  286. "a": map[string]any{
  287. "a": "1",
  288. "b": "2",
  289. },
  290. "b": map[string]string(nil),
  291. },
  292. "Nil": map[string]Base(nil),
  293. },
  294. "BaseIf": map[string]any{
  295. "Int": 1,
  296. "Bool": true,
  297. "String": "test",
  298. "Float": 1,
  299. },
  300. "NilPtr": (*Base)(nil),
  301. }
  302. mpRetJson, err := ObjectToJSON(retMp)
  303. So(err, ShouldBeNil)
  304. exceptMapJson, err := ObjectToJSON(exceptMap)
  305. So(err, ShouldBeNil)
  306. So(string(mpRetJson), ShouldEqualJSON, string(exceptMapJson))
  307. })
  308. Convey("包含UnionType", t, func() {
  309. type EleType string
  310. type UnionType interface{}
  311. type EleType1 struct {
  312. Metadata `union:"1"`
  313. Type EleType `json:"type"`
  314. Value1 string `json:"value1"`
  315. }
  316. type EleType2 struct {
  317. Metadata `union:"2"`
  318. Type EleType `json:"type"`
  319. Value2 int `json:"value2"`
  320. }
  321. type St struct {
  322. Us []UnionType `json:"us"`
  323. }
  324. mp := map[string]any{
  325. "us": []map[string]any{
  326. {
  327. "type": "1",
  328. "value1": "1",
  329. },
  330. {
  331. "type": "2",
  332. "value2": 2,
  333. },
  334. },
  335. }
  336. var ret St
  337. union := types.NewTypeUnion[UnionType](
  338. (*EleType1)(nil),
  339. (*EleType2)(nil),
  340. )
  341. UseTypeUnionInternallyTagged(&union, "type")
  342. err := MapToObject(mp, &ret)
  343. So(err, ShouldBeNil)
  344. So(ret.Us, ShouldResemble, []UnionType{
  345. &EleType1{Type: "1", Value1: "1"},
  346. &EleType2{Type: "2", Value2: 2},
  347. })
  348. })
  349. Convey("要转换到的结构体就是一个UnionType", t, func() {
  350. type UnionType interface{}
  351. type EleType1 struct {
  352. Metadata `union:"1"`
  353. Type string `json:"type"`
  354. Value1 string `json:"value1"`
  355. }
  356. type EleType2 struct {
  357. Metadata `union:"2"`
  358. Type string `json:"type"`
  359. Value2 int `json:"value2"`
  360. }
  361. mp := map[string]any{
  362. "type": "1",
  363. "value1": "1",
  364. }
  365. var ret UnionType
  366. union := types.NewTypeUnion[UnionType](
  367. (*EleType1)(nil),
  368. (*EleType2)(nil),
  369. )
  370. UseTypeUnionInternallyTagged(&union, "type")
  371. err := MapToObject(mp, &ret)
  372. So(err, ShouldBeNil)
  373. So(ret, ShouldResemble, &EleType1{Type: "1", Value1: "1"})
  374. })
  375. Convey("NewType", t, func() {
  376. type Str string
  377. type St struct {
  378. Str Str
  379. }
  380. mp := map[string]any{
  381. "Str": "1",
  382. }
  383. var ret St
  384. err := MapToObject(mp, &ret)
  385. So(err, ShouldBeNil)
  386. So(string(ret.Str), ShouldEqual, "1")
  387. })
  388. }
  389. type Base interface {
  390. Noop()
  391. }
  392. type St1 struct {
  393. Metadata `union:"St1"`
  394. Type string
  395. Val string
  396. }
  397. func (*St1) Noop() {}
  398. type St2 struct {
  399. Metadata `union:"St2"`
  400. Type string
  401. Val int
  402. }
  403. func (St2) Noop() {}
  404. func Test_ObjectToJSON2(t *testing.T) {
  405. Convey("NewType", t, func() {
  406. type Str string
  407. type St struct {
  408. Str Str `json:"str"`
  409. }
  410. st := St{
  411. Str: Str("1"),
  412. }
  413. data, err := ObjectToJSON(st)
  414. So(err, ShouldBeNil)
  415. var ret St
  416. err = JSONToObject(data, &ret)
  417. So(err, ShouldBeNil)
  418. So(string(ret.Str), ShouldEqual, "1")
  419. })
  420. Convey("UnionType ExternallyTagged", t, func() {
  421. type Base interface{}
  422. type St1 struct {
  423. Val string
  424. }
  425. type St2 struct {
  426. Val int64
  427. }
  428. type Outter struct {
  429. B []Base
  430. }
  431. union := types.NewTypeUnion[Base](St1{}, &St2{})
  432. UseTypeUnionExternallyTagged(&union)
  433. val := Outter{B: []Base{St1{Val: "asd"}, &St2{Val: 123}}}
  434. data, err := ObjectToJSONEx(val)
  435. So(err, ShouldBeNil)
  436. ret, err := JSONToObjectEx[Outter](data)
  437. So(err, ShouldBeNil)
  438. So(ret, ShouldResemble, val)
  439. })
  440. Convey("UnionType InternallyTagged", t, func() {
  441. type Base interface{}
  442. type St1 struct {
  443. Metadata `union:"St1"`
  444. Type string
  445. Val string
  446. }
  447. type St2 struct {
  448. Metadata `union:"St2"`
  449. Type string
  450. Val int64
  451. }
  452. type Outter struct {
  453. B []Base
  454. }
  455. union := types.NewTypeUnion[Base](St1{}, &St2{})
  456. UseTypeUnionInternallyTagged(&union, "Type")
  457. val := Outter{B: []Base{St1{Val: "asd", Type: "St1"}, &St2{Val: 123, Type: "St2"}}}
  458. data, err := ObjectToJSONEx(val)
  459. So(err, ShouldBeNil)
  460. ret, err := JSONToObjectEx[Outter](data)
  461. So(err, ShouldBeNil)
  462. So(ret, ShouldResemble, val)
  463. })
  464. Convey("实参类型和目标类型本身就是UnionType ExternallyTagged", t, func() {
  465. type Base interface{}
  466. type St1 struct {
  467. Val string
  468. }
  469. union := types.NewTypeUnion[Base](St1{})
  470. UseTypeUnionExternallyTagged(&union)
  471. var val Base = St1{Val: "asd"}
  472. data, err := ObjectToJSONEx(val)
  473. So(err, ShouldBeNil)
  474. ret, err := JSONToObjectEx[Base](data)
  475. So(err, ShouldBeNil)
  476. So(ret, ShouldResemble, val)
  477. })
  478. Convey("实参类型和目标类型本身就是UnionType InternallyTagged", t, func() {
  479. type Base interface{}
  480. type St1 struct {
  481. Metadata `union:"St1"`
  482. Type string
  483. Val string
  484. }
  485. union := types.NewTypeUnion[Base](St1{})
  486. UseTypeUnionInternallyTagged(&union, "Type")
  487. var val Base = St1{Val: "asd", Type: "St1"}
  488. data, err := ObjectToJSONEx(val)
  489. So(err, ShouldBeNil)
  490. ret, err := JSONToObjectEx[Base](data)
  491. So(err, ShouldBeNil)
  492. So(ret, ShouldResemble, val)
  493. })
  494. Convey("UnionType带有函数 ExternallyTagged", t, func() {
  495. union := types.NewTypeUnion[Base](&St1{}, St2{})
  496. UseTypeUnionExternallyTagged(&union)
  497. var val = []Base{
  498. &St1{Val: "asd", Type: "St1"},
  499. St2{Val: 123, Type: "St2"},
  500. }
  501. data, err := ObjectToJSONEx(val)
  502. So(err, ShouldBeNil)
  503. ret, err := JSONToObjectEx[[]Base](data)
  504. So(err, ShouldBeNil)
  505. So(ret, ShouldResemble, val)
  506. })
  507. Convey("UnionType带有函数 InternallyTagged", t, func() {
  508. union := types.NewTypeUnion[Base](&St1{}, St2{})
  509. UseTypeUnionInternallyTagged(&union, "Type")
  510. var val = []Base{
  511. &St1{Val: "asd", Type: "St1"},
  512. St2{Val: 123, Type: "St2"},
  513. }
  514. data, err := ObjectToJSONEx(val)
  515. So(err, ShouldBeNil)
  516. ret, err := JSONToObjectEx[[]Base](data)
  517. So(err, ShouldBeNil)
  518. So(ret, ShouldResemble, val)
  519. })
  520. Convey("UnionType,但实际值为nil ExternallyTagged", t, func() {
  521. union := types.NewTypeUnion[Base](&St1{}, St2{})
  522. UseTypeUnionExternallyTagged(&union)
  523. var val = []Base{
  524. nil,
  525. }
  526. data, err := ObjectToJSONEx(val)
  527. So(err, ShouldBeNil)
  528. ret, err := JSONToObjectEx[[]Base](data)
  529. So(err, ShouldBeNil)
  530. So(ret, ShouldResemble, val)
  531. })
  532. Convey("UnionType,但实际值为nil InternallyTagged", t, func() {
  533. union := types.NewTypeUnion[Base](&St1{}, St2{})
  534. UseTypeUnionInternallyTagged(&union, "Type")
  535. var val = []Base{
  536. nil,
  537. }
  538. data, err := ObjectToJSONEx(val)
  539. So(err, ShouldBeNil)
  540. ret, err := JSONToObjectEx[[]Base](data)
  541. So(err, ShouldBeNil)
  542. So(ret, ShouldResemble, val)
  543. })
  544. }
  545. func Test_ObjectToJSON3(t *testing.T) {
  546. Convey("反序列化TypeUnion时,JSON中对应字段类型不对", t, func() {
  547. type Base interface{}
  548. union := types.NewTypeUnion[Base](&St1{}, &St2{})
  549. UseTypeUnionInternallyTagged(&union, "Type")
  550. v, err := JSONToObjectEx[[]Base]([]byte("[{\"Type\":\"St2\", \"Val\":[]}]"))
  551. t.Logf("err: %v", err)
  552. t.Logf("v: %+v", v[0])
  553. So(err, ShouldNotBeNil)
  554. // So(ret, ShouldResemble, val)
  555. })
  556. }
  557. type BaseCallback interface{}
  558. type StCallback struct {
  559. Metadata `union:"StCallback"`
  560. Type string
  561. Value string
  562. }
  563. func (st *StCallback) OnUnionSerializing() {
  564. st.Value = "called"
  565. st.Type = "StCallback"
  566. }
  567. func Test_ObjectToJSONEx4(t *testing.T) {
  568. Convey("序列化Callback", t, func() {
  569. union := types.NewTypeUnion[BaseCallback](&StCallback{})
  570. UseTypeUnionInternallyTagged(&union, "Type")
  571. val := []BaseCallback{&StCallback{}}
  572. data, err := ObjectToJSONEx(val)
  573. So(err, ShouldBeNil)
  574. ret, err := JSONToObjectEx[[]BaseCallback](data)
  575. So(err, ShouldBeNil)
  576. So(len(ret), ShouldEqual, 1)
  577. So(ret[0].(*StCallback).Value, ShouldEqual, "called")
  578. })
  579. }
  580. type StStringer struct {
  581. }
  582. func (s StStringer) String() string {
  583. return "StStringer"
  584. }
  585. func Test_ObjectToMapString(t *testing.T) {
  586. Convey("结构体", t, func() {
  587. type StEmb struct {
  588. IntRef *int `json:"intRef,omitempty"`
  589. BoolRef **bool `json:"boolRef"`
  590. StrRef *string `json:"strRef"`
  591. }
  592. type St struct {
  593. StEmb
  594. Int int
  595. Bool bool
  596. Str string
  597. StStringer *StStringer
  598. }
  599. st := St{
  600. StEmb: StEmb{
  601. IntRef: types.Ref(123),
  602. BoolRef: types.Ref(types.Ref(true)),
  603. },
  604. Int: 456,
  605. Bool: false,
  606. Str: "test",
  607. StStringer: &StStringer{},
  608. }
  609. mp, err := ObjectToMapString(st)
  610. So(err, ShouldBeNil)
  611. So(mp["intRef"], ShouldEqual, "123")
  612. So(mp["boolRef"], ShouldEqual, "true")
  613. So(mp["strRef"], ShouldEqual, "")
  614. So(mp["Int"], ShouldEqual, "456")
  615. So(mp["Bool"], ShouldEqual, "false")
  616. So(mp["Str"], ShouldEqual, "test")
  617. So(mp["StStringer"], ShouldEqual, "StStringer")
  618. })
  619. Convey("结构体引用", t, func() {
  620. type StEmb struct {
  621. IntRef *int `json:"intRef,omitempty"`
  622. BoolRef **bool `json:"boolRef"`
  623. StrRef *string `json:"strRef"`
  624. }
  625. type St struct {
  626. StEmb
  627. Int int
  628. Bool bool
  629. Str string
  630. StStringer *StStringer
  631. }
  632. st := St{
  633. StEmb: StEmb{
  634. IntRef: types.Ref(123),
  635. BoolRef: types.Ref(types.Ref(true)),
  636. },
  637. Int: 456,
  638. Bool: false,
  639. Str: "test",
  640. StStringer: &StStringer{},
  641. }
  642. mp, err := ObjectToMapString(&st)
  643. So(err, ShouldBeNil)
  644. So(mp["intRef"], ShouldEqual, "123")
  645. So(mp["boolRef"], ShouldEqual, "true")
  646. So(mp["strRef"], ShouldEqual, "")
  647. So(mp["Int"], ShouldEqual, "456")
  648. So(mp["Bool"], ShouldEqual, "false")
  649. So(mp["Str"], ShouldEqual, "test")
  650. So(mp["StStringer"], ShouldEqual, "StStringer")
  651. })
  652. Convey("nil", t, func() {
  653. mp, err := ObjectToMapString(nil)
  654. So(err, ShouldBeNil)
  655. So(mp, ShouldResemble, map[string]string{})
  656. })
  657. Convey("nil指针", t, func() {
  658. type St struct{}
  659. var st *St
  660. mp, err := ObjectToMapString(st)
  661. So(err, ShouldBeNil)
  662. So(mp, ShouldResemble, map[string]string{})
  663. })
  664. Convey("非结构体", t, func() {
  665. mp, err := ObjectToMapString(123)
  666. So(err, ShouldNotBeNil)
  667. So(mp, ShouldBeNil)
  668. })
  669. }