6
\$\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));
}
\$\endgroup\$
  • 1
    \$\begingroup\$ If you put one assertion per test it doesn't look that verbose. \$\endgroup\$ – abuzittin gillifirca Jan 31 '14 at 11:34
  • \$\begingroup\$ I'm new in Unit Testing and I didn't know Automapper. What is fixture.Create? \$\endgroup\$ – VansFannel Oct 27 '17 at 8:41
  • \$\begingroup\$ @VansFannel it's actually from github.com/AutoFixture/AutoFixture \$\endgroup\$ – vorou Oct 28 '17 at 4:48
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).

\$\endgroup\$
  • \$\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\$ – vorou Jan 30 '14 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\$ – palacsint Jan 30 '14 at 21:15
  • \$\begingroup\$ I'm talking about reverse mapping, I don't have such method right now. \$\endgroup\$ – vorou Jan 31 '14 at 9:22
  • \$\begingroup\$ @vorou: I've update the answer a little bit. \$\endgroup\$ – palacsint Feb 1 '14 at 10:20
5
\$\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));
    }
\$\endgroup\$
  • \$\begingroup\$ Note that OmitAutoProperties will disable this functionality. It is on by default. \$\endgroup\$ – PMBjornerud Feb 17 '16 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.