8
\$\begingroup\$

Obviously, you have to test mapping code somehow, even (or especially) if you use AutoMapper. Is there any way to make it less verbose?

[Test]
public void Map_Always_SetsSimpleProperties()
{
 var auctionPlace = fixture.Create<string>();
 var submissionCloseDateTime = fixture.Create<DateTime>();
 var quotationForm = fixture.Create<string>();
 var quotationExaminationDateTime = fixture.Create<DateTime>();
 var envelopeOpeningTime = fixture.Create<DateTime>();
 var envelopeOpeningPlace = fixture.Create<string>();
 var auctionDateTime = fixture.Create<DateTime>();
 var applExamPeriodDateTime = fixture.Create<DateTime>();
 var considerationSecondPartDate = fixture.Create<DateTime>();
 var doc = fixture.Create<Notification223>();
 doc.AuctionPlace = auctionPlace;
 doc.SubmissionCloseDateTime = submissionCloseDateTime;
 doc.QuotationForm = quotationForm;
 doc.QuotationExaminationTime = quotationExaminationDateTime;
 doc.EnvelopeOpeningTime = envelopeOpeningTime;
 doc.EnvelopeOpeningPlace = envelopeOpeningPlace;
 doc.AuctionTime = auctionDateTime;
 doc.ApplExamPeriodTime = applExamPeriodDateTime;
 doc.ConsiderationSecondPartDate = considerationSecondPartDate;
 var sut = CreateSut();
 var actual = sut.Map(doc);
 Assert.That(actual.AuctionPlace, Is.EqualTo(auctionPlace));
 Assert.That(actual.SubmissionCloseDateTime, Is.EqualTo(submissionCloseDateTime));
 Assert.That(actual.QuotationForm, Is.EqualTo(quotationForm));
 Assert.That(actual.QuotationExaminationDateTime, Is.EqualTo(quotationExaminationDateTime));
 Assert.That(actual.EnvelopeOpeningTime, Is.EqualTo(envelopeOpeningTime));
 Assert.That(actual.EnvelopeOpeningPlace, Is.EqualTo(envelopeOpeningPlace));
 Assert.That(actual.AuctionDateTime, Is.EqualTo(auctionDateTime));
 Assert.That(actual.ApplExamPeriodDateTime, Is.EqualTo(applExamPeriodDateTime));
 Assert.That(actual.ConsiderationSecondPartDate, Is.EqualTo(considerationSecondPartDate));
}
palacsint
30.4k9 gold badges82 silver badges157 bronze badges
asked Jan 29, 2014 at 10:47
\$\endgroup\$
3
  • 1
    \$\begingroup\$ If you put one assertion per test it doesn't look that verbose. \$\endgroup\$ Commented Jan 31, 2014 at 11:34
  • \$\begingroup\$ I'm new in Unit Testing and I didn't know Automapper. What is fixture.Create? \$\endgroup\$ Commented Oct 27, 2017 at 8:41
  • \$\begingroup\$ @VansFannel it's actually from github.com/AutoFixture/AutoFixture \$\endgroup\$ Commented Oct 28, 2017 at 4:48

2 Answers 2

4
\$\begingroup\$

Unfortunately, I don't think so.

There is a question about this topic on the website of Dozer (which is a similar library for Java) which mentions a trick:

Should I write unit tests for data mapping logic that I use Dozer to perform?

[...]

Regardless of whether or not you use Dozer, unit testing data mapping logic is tedious and a necessary evil, but there is a trick that may help. If you have an assembler that supports mapping 2 objects bi-directionally, in your unit test you can do something similar to the following example. This also assumes you have done a good job of implementing the equals() method for your data objects. The idea is that if you map a source object to a destination object and then back again, the original src object should equal the object returned from the last mapping if fields were mapped correctly. [...]

I think this trick won't find bugs when, for example, doc.ApplExamPeriodTime is mapped to actual.ConsiderationSecondPartDate and doc.ConsiderationSecondPartDate is mapped to actual.ApplExamPeriodTime. I don't know that these kind of bugs are possible with AutoMapper or not.

Furthermore, if you need only one directional mapping, I think the most simple solution is the one that's already in your question, I'd go with that. Adding code for the reverse mapping to the production code would be a test smell (Test Logic in Production).

answered Jan 29, 2014 at 22:24
\$\endgroup\$
4
  • \$\begingroup\$ Well, what if I actually need only one direction? I strongly dislike the idea of putting something in a public API just for sake of testing. \$\endgroup\$ Commented Jan 30, 2014 at 3:36
  • \$\begingroup\$ @vorou: I think in that case the only solution is that that you showed in your question. What method do you think of as putting it public for only testing? \$\endgroup\$ Commented Jan 30, 2014 at 21:15
  • \$\begingroup\$ I'm talking about reverse mapping, I don't have such method right now. \$\endgroup\$ Commented Jan 31, 2014 at 9:22
  • \$\begingroup\$ @vorou: I've update the answer a little bit. \$\endgroup\$ Commented Feb 1, 2014 at 10:20
8
\$\begingroup\$

Yes, you can make it less verbose.

I assume you are using AutoFixture in you call to Create()?

If so, this will create random values out of the box. No need to specify the content and assign each property. Create the source object for mapping, map it, compare the mapped values with the properties on the source object:

 [Test]
 public void Map_Always_SetsSimpleProperties()
 {
 var doc = fixture.Create<Notification223>(); // Autofixture will fill properties with random data.
 var sut = CreateSut();
 var actual = sut.Map(doc);
 Assert.That(actual.AuctionPlace, Is.EqualTo(doc.AuctionPlace));
 Assert.That(actual.SubmissionCloseDateTime, Is.EqualTo(doc.SubmissionCloseDateTime));
 Assert.That(actual.QuotationForm, Is.EqualTo(doc.QuotationForm));
 Assert.That(actual.QuotationExaminationDateTime, Is.EqualTo(doc.QuotationExaminationDateTime));
 Assert.That(actual.EnvelopeOpeningTime, Is.EqualTo(doc.EnvelopeOpeningTime));
 Assert.That(actual.EnvelopeOpeningPlace, Is.EqualTo(doc.EnvelopeOpeningPlace));
 Assert.That(actual.AuctionDateTime, Is.EqualTo(doc.AuctionDateTime));
 Assert.That(actual.ApplExamPeriodDateTime, Is.EqualTo(doc.ApplExamPeriodDateTime));
 Assert.That(actual.ConsiderationSecondPartDate, Is.EqualTo(doc.ConsiderationSecondPartDate));
 }
answered Feb 17, 2016 at 9:29
\$\endgroup\$
1
  • \$\begingroup\$ Note that OmitAutoProperties will disable this functionality. It is on by default. \$\endgroup\$ Commented Feb 17, 2016 at 9:49

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.