PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/Dev/Contributions/FluentAssertions.Specs/PropertyAssertionSpecs.cs

#
C# | 743 lines | 457 code | 103 blank | 183 comment | 1 complexity | 33186057b664e7665e26c3b6b0579ba0 MD5 | raw file
  1. using System;
  2. using FluentAssertions.Assertions;
  3. using FluentAssertions.Specs;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. namespace FluentAssertions.specs
  6. {
  7. [TestClass]
  8. public class PropertyAssertionSpecs
  9. {
  10. #region Property Comparison
  11. [TestMethod]
  12. public void When_two_objects_have_the_same_property_values_it_should_not_throw()
  13. {
  14. //-----------------------------------------------------------------------------------------------------------
  15. // Arrange
  16. //-----------------------------------------------------------------------------------------------------------
  17. var subject = new
  18. {
  19. Age = 36,
  20. Birthdate = new DateTime(1973, 9, 20),
  21. Name = "Dennis"
  22. };
  23. var other = new
  24. {
  25. Age = 36,
  26. Birthdate = new DateTime(1973, 9, 20),
  27. Name = "Dennis"
  28. };
  29. //-----------------------------------------------------------------------------------------------------------
  30. // Act / Assert
  31. //-----------------------------------------------------------------------------------------------------------
  32. subject.ShouldHave().AllProperties().EqualTo(other);
  33. }
  34. [TestMethod]
  35. public void When_two_objects_have_the_same_properties_but_a_different_value_it_should_throw()
  36. {
  37. //-----------------------------------------------------------------------------------------------------------
  38. // Arrange
  39. //-----------------------------------------------------------------------------------------------------------
  40. var subject = new
  41. {
  42. Age = 36,
  43. };
  44. var other = new
  45. {
  46. Age = 37,
  47. };
  48. //-----------------------------------------------------------------------------------------------------------
  49. // Act
  50. //-----------------------------------------------------------------------------------------------------------
  51. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other, "because {0} are the same", "they");
  52. //-----------------------------------------------------------------------------------------------------------
  53. // Assert
  54. //-----------------------------------------------------------------------------------------------------------
  55. act.ShouldThrow<AssertFailedException>().WithMessage(
  56. "Expected property Age to be 37 because they are the same, but found 36.");
  57. }
  58. [TestMethod]
  59. public void When_subject_has_a_valid_property_that_is_compared_with_a_null_property_it_should_throw()
  60. {
  61. //-----------------------------------------------------------------------------------------------------------
  62. // Arrange
  63. //-----------------------------------------------------------------------------------------------------------
  64. var subject = new
  65. {
  66. Name = "Dennis"
  67. };
  68. var other = new
  69. {
  70. Name = (string) null
  71. };
  72. //-----------------------------------------------------------------------------------------------------------
  73. // Act
  74. //-----------------------------------------------------------------------------------------------------------
  75. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  76. //-----------------------------------------------------------------------------------------------------------
  77. // Assert
  78. //-----------------------------------------------------------------------------------------------------------
  79. act.ShouldThrow<AssertFailedException>().WithMessage(
  80. "Expected property Name to be <null>, but found \"Dennis\".");
  81. }
  82. [TestMethod]
  83. public void When_two_collection_properties_dont_match_it_should_throw_and_specify_the_difference()
  84. {
  85. //-----------------------------------------------------------------------------------------------------------
  86. // Arrange
  87. //-----------------------------------------------------------------------------------------------------------
  88. var subject = new
  89. {
  90. Values = new [] { 1, 2, 3 }
  91. };
  92. var other = new
  93. {
  94. Values = new [] { 1, 4, 3 }
  95. };
  96. //-----------------------------------------------------------------------------------------------------------
  97. // Act
  98. //-----------------------------------------------------------------------------------------------------------
  99. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  100. //-----------------------------------------------------------------------------------------------------------
  101. // Assert
  102. //-----------------------------------------------------------------------------------------------------------
  103. act.ShouldThrow<AssertFailedException>().WithMessage(
  104. "Expected property Values to be equal to {1, 4, 3}, but {1, 2, 3} differs at index 1.");
  105. }
  106. [TestMethod]
  107. public void When_two_objects_have_the_same_properties_with_convertable_values_it_should_not_throw()
  108. {
  109. //-----------------------------------------------------------------------------------------------------------
  110. // Arrange
  111. //-----------------------------------------------------------------------------------------------------------
  112. var subject = new
  113. {
  114. Age = "37",
  115. Birthdate = "1973-09-20",
  116. };
  117. var other = new
  118. {
  119. Age = 37,
  120. Birthdate = new DateTime(1973, 9, 20)
  121. };
  122. //-----------------------------------------------------------------------------------------------------------
  123. // Act
  124. //-----------------------------------------------------------------------------------------------------------
  125. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  126. //-----------------------------------------------------------------------------------------------------------
  127. // Assert
  128. //-----------------------------------------------------------------------------------------------------------
  129. act.ShouldNotThrow();
  130. }
  131. [TestMethod]
  132. public void When_two_string_properties_do_not_match_it_should_throw_and_state_the_difference()
  133. {
  134. //-----------------------------------------------------------------------------------------------------------
  135. // Arrange
  136. //-----------------------------------------------------------------------------------------------------------
  137. var subject = new
  138. {
  139. Name = "Dennes"
  140. };
  141. var other = new
  142. {
  143. Name = "Dennis"
  144. };
  145. //-----------------------------------------------------------------------------------------------------------
  146. // Act
  147. //-----------------------------------------------------------------------------------------------------------
  148. Action act = () => subject.ShouldHave().Properties(d => d.Name).EqualTo(other);
  149. //-----------------------------------------------------------------------------------------------------------
  150. // Assert
  151. //-----------------------------------------------------------------------------------------------------------
  152. act.ShouldThrow<AssertFailedException>().WithMessage(
  153. "Expected property Name to be \"Dennis\", but \"Dennes\" differs near \"es\" (index 4).");
  154. }
  155. #endregion
  156. #region Structure Comparison
  157. [TestMethod]
  158. public void When_subject_has_a_property_not_available_in_expected_object_it_should_throw()
  159. {
  160. //-----------------------------------------------------------------------------------------------------------
  161. // Arrange
  162. //-----------------------------------------------------------------------------------------------------------
  163. var subject = new
  164. {
  165. City = "Rijswijk"
  166. };
  167. var other = new
  168. {
  169. };
  170. //-----------------------------------------------------------------------------------------------------------
  171. // Act
  172. //-----------------------------------------------------------------------------------------------------------
  173. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  174. //-----------------------------------------------------------------------------------------------------------
  175. // Assert
  176. //-----------------------------------------------------------------------------------------------------------
  177. act.ShouldThrow<AssertFailedException>().WithMessage(
  178. "Subject has property City that the other object does not have.");
  179. }
  180. [TestMethod]
  181. public void When_subjects_properties_are_compared_to_null_object_it_should_throw()
  182. {
  183. //-----------------------------------------------------------------------------------------------------------
  184. // Arrange
  185. //-----------------------------------------------------------------------------------------------------------
  186. var subject = new
  187. {
  188. };
  189. //-----------------------------------------------------------------------------------------------------------
  190. // Act
  191. //-----------------------------------------------------------------------------------------------------------
  192. Action act = () => subject.ShouldHave().AllProperties().EqualTo(null);
  193. //-----------------------------------------------------------------------------------------------------------
  194. // Assert
  195. //-----------------------------------------------------------------------------------------------------------
  196. act.ShouldThrow<NullReferenceException>().WithMessage(
  197. "Cannot compare subject's properties with a <null> object.");
  198. }
  199. [TestMethod]
  200. public void When_subject_is_null_it_should_throw()
  201. {
  202. //-----------------------------------------------------------------------------------------------------------
  203. // Arrange
  204. //-----------------------------------------------------------------------------------------------------------
  205. SomeDto subject = null;
  206. //-----------------------------------------------------------------------------------------------------------
  207. // Act
  208. //-----------------------------------------------------------------------------------------------------------
  209. Action act = () => subject.ShouldHave().AllProperties().EqualTo(new
  210. {
  211. });
  212. //-----------------------------------------------------------------------------------------------------------
  213. // Assert
  214. //-----------------------------------------------------------------------------------------------------------
  215. act.ShouldThrow<NullReferenceException>().WithMessage(
  216. "Cannot compare the properties of a <null> object.");
  217. }
  218. [TestMethod]
  219. public void When_comparing_objects_it_should_ignore_private_properties()
  220. {
  221. //-----------------------------------------------------------------------------------------------------------
  222. // Arrange
  223. //-----------------------------------------------------------------------------------------------------------
  224. var subject = new
  225. {
  226. Age = 36,
  227. Birthdate = new DateTime(1973, 9, 20),
  228. Name = "John",
  229. };
  230. var other = new
  231. {
  232. Age = 36,
  233. Birthdate = new DateTime(1973, 9, 20),
  234. Name = "John"
  235. };
  236. //-----------------------------------------------------------------------------------------------------------
  237. // Act
  238. //-----------------------------------------------------------------------------------------------------------
  239. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  240. //-----------------------------------------------------------------------------------------------------------
  241. // Assert
  242. //-----------------------------------------------------------------------------------------------------------
  243. act.ShouldNotThrow();
  244. }
  245. [TestMethod]
  246. public void When_equally_named_properties_are_type_incompatiblle_it_should_throw()
  247. {
  248. //-----------------------------------------------------------------------------------------------------------
  249. // Arrange
  250. //-----------------------------------------------------------------------------------------------------------
  251. var subject = new
  252. {
  253. Type = "A",
  254. };
  255. var other = new
  256. {
  257. Type = 36,
  258. };
  259. //-----------------------------------------------------------------------------------------------------------
  260. // Act
  261. //-----------------------------------------------------------------------------------------------------------
  262. Action act = () => subject.ShouldHave().AllProperties().EqualTo(other);
  263. //-----------------------------------------------------------------------------------------------------------
  264. // Assert
  265. //-----------------------------------------------------------------------------------------------------------
  266. act
  267. .ShouldThrow<AssertFailedException>()
  268. .WithMessage("Expected property Type to be 36, but found \"A\" which is of an incompatible type.");
  269. }
  270. #endregion
  271. #region Property Inclusion & Exclusion
  272. [TestMethod]
  273. public void When_specific_properties_of_a_subject_are_compared_with_another_object_it_should_ignore_the_other_properties()
  274. {
  275. //-----------------------------------------------------------------------------------------------------------
  276. // Arrange
  277. //-----------------------------------------------------------------------------------------------------------
  278. var subject = new
  279. {
  280. Age = 36,
  281. Birthdate = new DateTime(1973, 9, 20),
  282. Name = "John"
  283. };
  284. var customer = new
  285. {
  286. Age = 36,
  287. Birthdate = new DateTime(1973, 9, 20),
  288. Name = "Dennis"
  289. };
  290. //-----------------------------------------------------------------------------------------------------------
  291. // Act
  292. //-----------------------------------------------------------------------------------------------------------
  293. Action act = () => subject.ShouldHave().Properties(d => d.Age, d => d.Birthdate).EqualTo(customer);
  294. //-----------------------------------------------------------------------------------------------------------
  295. // Assert
  296. //-----------------------------------------------------------------------------------------------------------
  297. act.ShouldNotThrow();
  298. }
  299. [TestMethod]
  300. public void When_property_is_compared_but_a_nonproperty_is_specified_it_should_throw()
  301. {
  302. //-----------------------------------------------------------------------------------------------------------
  303. // Arrange
  304. //-----------------------------------------------------------------------------------------------------------
  305. var dto = new CustomerDto();
  306. //-----------------------------------------------------------------------------------------------------------
  307. // Act
  308. //-----------------------------------------------------------------------------------------------------------
  309. Action act = () => dto.ShouldHave().Properties(d => d.GetType()).EqualTo(dto);
  310. //-----------------------------------------------------------------------------------------------------------
  311. // Assert
  312. //-----------------------------------------------------------------------------------------------------------
  313. act.ShouldThrow<ArgumentException>().WithMessage(
  314. "Cannot use <d.GetType()> when a property expression is expected.");
  315. }
  316. [TestMethod]
  317. public void When_subject_property_lambda_is_null_it_should_throw()
  318. {
  319. //-----------------------------------------------------------------------------------------------------------
  320. // Arrange
  321. //-----------------------------------------------------------------------------------------------------------
  322. var dto = new CustomerDto();
  323. //-----------------------------------------------------------------------------------------------------------
  324. // Act
  325. //-----------------------------------------------------------------------------------------------------------
  326. Action act = () => dto.ShouldHave().Properties(null).EqualTo(dto);
  327. //-----------------------------------------------------------------------------------------------------------
  328. // Assert
  329. //-----------------------------------------------------------------------------------------------------------
  330. act.ShouldThrow<NullReferenceException>().WithMessage(
  331. "Expected a property expression, but found <null>.");
  332. }
  333. [TestMethod]
  334. public void When_all_properties_but_one_match_and_that_is_expected_it_should_not_throw()
  335. {
  336. //-----------------------------------------------------------------------------------------------------------
  337. // Arrange
  338. //-----------------------------------------------------------------------------------------------------------
  339. var dto = new CustomerDto
  340. {
  341. Age = 36,
  342. Birthdate = new DateTime(1973, 9, 20),
  343. Name = "John"
  344. };
  345. var customer = new Customer
  346. {
  347. Age = 36,
  348. Birthdate = new DateTime(1973, 9, 20),
  349. Name = "Dennis"
  350. };
  351. //-----------------------------------------------------------------------------------------------------------
  352. // Act / Assert
  353. //-----------------------------------------------------------------------------------------------------------
  354. dto.ShouldHave().AllPropertiesBut(d => d.Name).EqualTo(customer);
  355. }
  356. [TestMethod]
  357. public void When_comparing_objects_by_their_shared_properties_and_all_match_it_should_not_throw()
  358. {
  359. //-----------------------------------------------------------------------------------------------------------
  360. // Arrange
  361. //-----------------------------------------------------------------------------------------------------------
  362. var dto = new CustomerDto
  363. {
  364. Version = 2,
  365. Age = 36,
  366. Birthdate = new DateTime(1973, 9, 20),
  367. Name = "John"
  368. };
  369. var customer = new Customer
  370. {
  371. Id = 1,
  372. Version = 2,
  373. Age = 36,
  374. Birthdate = new DateTime(1973, 9, 20),
  375. Name = "John"
  376. };
  377. //-----------------------------------------------------------------------------------------------------------
  378. // Act
  379. //-----------------------------------------------------------------------------------------------------------
  380. Action act = () => customer.ShouldHave().SharedProperties().EqualTo(dto);
  381. //-----------------------------------------------------------------------------------------------------------
  382. // Assert
  383. //-----------------------------------------------------------------------------------------------------------
  384. act.ShouldNotThrow();
  385. }
  386. [TestMethod]
  387. public void When_comparing_objects_by_their_properties_and_no_properties_have_been_specified_it_should_throw()
  388. {
  389. //-----------------------------------------------------------------------------------------------------------
  390. // Arrange
  391. //-----------------------------------------------------------------------------------------------------------
  392. var dto = new CustomerDto();
  393. var customer = new Customer();
  394. //-----------------------------------------------------------------------------------------------------------
  395. // Act
  396. //-----------------------------------------------------------------------------------------------------------
  397. Action act = () => dto.ShouldHave().EqualTo(customer);
  398. //-----------------------------------------------------------------------------------------------------------
  399. // Assert
  400. //-----------------------------------------------------------------------------------------------------------
  401. act.ShouldThrow<InvalidOperationException>().WithMessage(
  402. "Please specify some properties to include in the comparison.");
  403. }
  404. #endregion
  405. #region Recursive property validation
  406. [TestMethod]
  407. public void When_recursing_on_incompatible_properties_that_have_equal_child_properties_it_should_succeed()
  408. {
  409. //-----------------------------------------------------------------------------------------------------------
  410. // Arrange
  411. //-----------------------------------------------------------------------------------------------------------
  412. var root = new Root
  413. {
  414. Text = "Root",
  415. Level = new Level1
  416. {
  417. Text = "Level1",
  418. Level = new Level2
  419. {
  420. Text = "Level2",
  421. }
  422. }
  423. };
  424. var equalRootDto = new RootDto
  425. {
  426. Text = "Root",
  427. Level = new Level1Dto
  428. {
  429. Text = "Level1",
  430. Level = new Level2Dto
  431. {
  432. Text = "Level2",
  433. }
  434. }
  435. };
  436. //-----------------------------------------------------------------------------------------------------------
  437. // Act
  438. //-----------------------------------------------------------------------------------------------------------
  439. Action act = () =>
  440. root.ShouldHave().AllProperties().RecurseIfIncompatible().EqualTo(equalRootDto);
  441. //-----------------------------------------------------------------------------------------------------------
  442. // Assert
  443. //-----------------------------------------------------------------------------------------------------------
  444. act.ShouldNotThrow();
  445. }
  446. [TestMethod]
  447. public void When_not_recursing_on_incompatible_properties_that_have_equal_child_properties_it_should_throw()
  448. {
  449. //-----------------------------------------------------------------------------------------------------------
  450. // Arrange
  451. //-----------------------------------------------------------------------------------------------------------
  452. var root = new Root
  453. {
  454. Text = "Root",
  455. Level = new Level1
  456. {
  457. Text = "Level1",
  458. }
  459. };
  460. var equalRootDto = new RootDto
  461. {
  462. Text = "Root",
  463. Level = new Level1Dto
  464. {
  465. Text = "Level1",
  466. }
  467. };
  468. //-----------------------------------------------------------------------------------------------------------
  469. // Act
  470. //-----------------------------------------------------------------------------------------------------------
  471. Action act = () =>
  472. root.ShouldHave().AllProperties().EqualTo(equalRootDto);
  473. //-----------------------------------------------------------------------------------------------------------
  474. // Assert
  475. //-----------------------------------------------------------------------------------------------------------
  476. act
  477. .ShouldThrow<AssertFailedException>()
  478. .WithMessage("Expected property Level to be \r\n\r\nFluentAssertions.specs.Level1Dto\r\n" +
  479. "{\r\n Level = <null>\r\n Text = \"Level1\"\r\n}" +
  480. ", but found \r\n\r\nFluentAssertions.specs.Level1\r\n" +
  481. "{\r\n Level = <null>\r\n Text = \"Level1\"\r\n}" +
  482. " which is of an incompatible type.");
  483. }
  484. [TestMethod]
  485. public void When_recursing_on_incompatible_properties_that_have_differences_in_their_child_properties_it_should_throw()
  486. {
  487. //-----------------------------------------------------------------------------------------------------------
  488. // Arrange
  489. //-----------------------------------------------------------------------------------------------------------
  490. var root = new Root
  491. {
  492. Text = "Root",
  493. Level = new Level1
  494. {
  495. Text = "Level1",
  496. Level = new Level2
  497. {
  498. Text = "Level2",
  499. }
  500. }
  501. };
  502. var rootDto = new RootDto
  503. {
  504. Text = "Root",
  505. Level = new Level1Dto
  506. {
  507. Text = "Level1",
  508. Level = new Level2Dto
  509. {
  510. Text = "A wrong text value",
  511. }
  512. }
  513. };
  514. //-----------------------------------------------------------------------------------------------------------
  515. // Act
  516. //-----------------------------------------------------------------------------------------------------------
  517. Action act = () =>
  518. root.ShouldHave().AllProperties().RecurseIfIncompatible().EqualTo(rootDto);
  519. //-----------------------------------------------------------------------------------------------------------
  520. // Assert
  521. //-----------------------------------------------------------------------------------------------------------
  522. act
  523. .ShouldThrow<AssertFailedException>()
  524. .WithMessage("Expected property Level to have all properties equal to \r\n\r\n" +
  525. "FluentAssertions.specs.Level1Dto\r\n" +
  526. "{\r\n Level = FluentAssertions.specs.Level2Dto" +
  527. "\r\n {\r\n Text = \"A wrong text value\"\r\n }\r\n Text = \"Level1\"\r\n}" +
  528. ", but found \r\n\r\n" +
  529. "FluentAssertions.specs.Level1\r\n" +
  530. "{\r\n Level = FluentAssertions.specs.Level2" +
  531. "\r\n {\r\n Text = \"Level2\"\r\n }\r\n Text = \"Level1\"\r\n}.");
  532. }
  533. [TestMethod]
  534. public void When_recursing_on_incompatible_properties_that_have_cyclic_references_it_should_throw()
  535. {
  536. //-----------------------------------------------------------------------------------------------------------
  537. // Arrange
  538. //-----------------------------------------------------------------------------------------------------------
  539. var cyclicRoot = new CyclicRoot
  540. {
  541. Text = "Root",
  542. };
  543. cyclicRoot.Level = new CyclicLevel1
  544. {
  545. Text = "Level1",
  546. Root = cyclicRoot
  547. };
  548. var cyclicRootDto = new CyclicRootDto
  549. {
  550. Text = "Root",
  551. };
  552. cyclicRootDto.Level = new CyclicLevel1Dto
  553. {
  554. Text = "Level1",
  555. Root = cyclicRootDto
  556. };
  557. //-----------------------------------------------------------------------------------------------------------
  558. // Act
  559. //-----------------------------------------------------------------------------------------------------------
  560. Action act = () =>
  561. cyclicRoot.ShouldHave().AllProperties().RecurseIfIncompatible().EqualTo(cyclicRootDto);
  562. //-----------------------------------------------------------------------------------------------------------
  563. // Assert
  564. //-----------------------------------------------------------------------------------------------------------
  565. act
  566. .ShouldThrow<AssertFailedException>()
  567. .WithMessage("Expected property Level to be FluentAssertions.specs.CyclicLevel1Dto, but found " +
  568. "FluentAssertions.specs.CyclicLevel1 which is of an incompatible type and has a cyclic reference.");
  569. }
  570. #endregion
  571. }
  572. internal class Customer : Entity
  573. {
  574. public string Name { get; set; }
  575. public int Age { get; set; }
  576. public DateTime Birthdate { get; set; }
  577. public long Id { get; set; }
  578. }
  579. public class Entity
  580. {
  581. internal long Version { get; set; }
  582. }
  583. internal class CustomerDto
  584. {
  585. public long Version { get; set; }
  586. public string Name { get; set; }
  587. public int Age { get; set; }
  588. public DateTime Birthdate { get; set; }
  589. }
  590. #region Nested classes for comparison
  591. internal class Root
  592. {
  593. public string Text { get; set; }
  594. public Level1 Level { get; set; }
  595. }
  596. internal class Level1
  597. {
  598. public string Text { get; set; }
  599. public Level2 Level { get; set; }
  600. }
  601. internal class Level2
  602. {
  603. public string Text { get; set; }
  604. }
  605. internal class RootDto
  606. {
  607. public string Text { get; set; }
  608. public Level1Dto Level { get; set; }
  609. }
  610. internal class Level1Dto
  611. {
  612. public string Text { get; set; }
  613. public Level2Dto Level { get; set; }
  614. }
  615. internal class Level2Dto
  616. {
  617. public string Text { get; set; }
  618. }
  619. internal class CyclicRoot
  620. {
  621. public string Text { get; set; }
  622. public CyclicLevel1 Level { get; set; }
  623. }
  624. internal class CyclicLevel1
  625. {
  626. public string Text { get; set; }
  627. public CyclicRoot Root { get; set; }
  628. }
  629. internal class CyclicRootDto
  630. {
  631. public string Text { get; set; }
  632. public CyclicLevel1Dto Level { get; set; }
  633. }
  634. internal class CyclicLevel1Dto
  635. {
  636. public string Text { get; set; }
  637. public CyclicRootDto Root { get; set; }
  638. }
  639. #endregion
  640. }