chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I've talked about this before, and it's still bugging me! ;-)

Currently I have the following code (where XElement is LINQ to XML XElement, so include System.XML and System.XML.Linq)

public void GenerateXml()
{
   InvoiceInfo = invoiceInfo;

   // First element is created
   XElement subElement = new XElement("Invoices", new XAttribute("companycode", 13), new XAttribute("companyname", "Typemock"));
   // Second element is created, first element is inserted as subnode
   XElement rootElement = new XElement("root", subElement);

}


I have the following test code:

// Arrange
var firstElement = Isolate.Fake.Instance<XElement>(Members.CallOriginal, ConstructorWillBe.Called, XName.Get("Invoices"));
Isolate.Swap.NextInstance<XElement>().With(firstElement);
var secondElement = Isolate.Fake.Instance<XElement>(Members.CallOriginal, ConstructorWillBe.Called, XName.Get("Dude"));
Isolate.Swap.NextInstance<XElement>().With(secondElement);

XElement original = new XElement("ExactRoot");
Isolate.Swap.CallsOn(secondElement).WithCallsTo(original);

// Act
myClass.GenerateXML();

// Assert
// Do some assertions on original, as if it was the root element from the code that's under test


This doesn't work, at all! :)
First off all, I think that all calls to secondElement are actually swapped from firstElement.
Second of all, I have to set constructor calls, where I override the original behavior.

Now the following DOES work as I want it to...

[TestMethod]
public void TestName()
{
   // Arrange
   MockManager.Init();
   var first = MockManager.Mock<XElement>(Constructor.NotMocked);
   var second = MockManager.Mock<XElement>(Constructor.NotMocked);         

   // Act
   exactGenerator.GenerateXml();

   // Assert
   var root = second.MockedInstance as XElement;
   Assert.AreEqual("root", root.Name.LocalName);
   Assert.AreEqual("Typemock", root.Elements("Invoices").First().Attribute("companyname").Value);
}


How would I go about making this work under AAA API? And did I actually find a bug in the CallsOn behavior?

Thanks
asked by dvdstelt (5.3k points)

1 Answer

0 votes
Hi Dennis,

It took me a while to verify that indeed there is a bug hidden here. Let's start by how I would test this:

// we need to call a specific constructor because the XElement c'tor doesn't take null
var first = Isolate.Fake.Instance<XElement>(Members.CallOriginal, ConstructorWillBe.Called, XName.Get("test1"));
var second = Isolate.Fake.Instance<XElement>(Members.CallOriginal, ConstructorWillBe.Called, XName.Get("test2"));

Isolate.Swap.NextInstance<XElement>().With(first);
Isolate.Swap.NextInstance<XElement>().With(second);

myClass.GenerateXml();

Assert.AreEqual("root", second.Name.LocalName);
Assert.AreEqual("Typemock", second.Elements("Invoices").First().Attribute("companyname").Value);


However, this test fails because the field values set in the initialization inside GenerateXml() were not transferred to the swapping fakes in the test. This is a bug, and I'll fix that in the next couple of days - I will send you a patched version early next week.

Thanks for an excellent report!
Doron
Typemock Support
answered by doron (17.2k points)
...