Pex looks interesting from a characterisation testing perspective but I'm having trouble getting it to assert a change in an object passed by reference.
Given the code that I'm trying to test below:
public class ItemUpdater
{
public void Update(Item item)
{
if (item.Name == "Two Times")
{
item.Quantity = item.Quantity*2;
}
if (item.Name == "Two more") {
item.Quantity = item.Quantity + 2;
}
}
}
public class Item
{
public string Name { get; set; }
public int Quantity { get; set; }
}
What I'm looking to do is Create and Run intellitest tests against Update that will generate Characterisation/Locking tests so that I can make changes.
When tests are generated I get:
[TestClass]
[PexClass(typeof(ItemUpdater))]
[PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
[PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
public partial class ItemUpdaterTest
{
/// <summary>Test stub for Update(Item)</summary>
[PexMethod]
public void UpdateTest([PexAssumeUnderTest]ItemUpdater target, Item item) {
PexAssume.IsNotNull(item);
target.Update(item);
var quality = item.Quantity;
PexAssert.AreEqual(quality, item.Quantity);
// TODO: add assertions to method ItemUpdaterTest.UpdateTest(ItemUpdater, Item)
}
}
I've added an assume to remove the null check tests, no problem here.
The problem I'm having is getting intellitest to auto-generate the item.Quantity assertions. I've also tried passing the quality as a parameter to UpdateTest(...., int quality) but this is always set to zero.
All that comes out is:
[TestMethod]
[PexGeneratedBy(typeof(ItemUpdaterTest))]
public void UpdateTest515()
{
ItemUpdater s0 = new ItemUpdater();
Item s1 = new Item();
s1.Name = "Two more";
s1.Quantity = 0;
this.UpdateTest(s0, s1);
Assert.IsNotNull((object)s0);
}
No asserting against the value of item.Quantity.
Does anyone know how to get Pex/Intellitest to generate assertions against the returned item.Quality after the Update method has been called?
I found out how to do this. The answer is to add PexObserve.ValueAtEndOfTest like so:
[TestClass]
[PexClass(typeof(ItemUpdater))]
[PexAllowedExceptionFromTypeUnderTest(typeof(ArgumentException), AcceptExceptionSubtypes = true)]
[PexAllowedExceptionFromTypeUnderTest(typeof(InvalidOperationException))]
public partial class ItemUpdaterTest
{
/// <summary>Test stub for Update(Item)</summary>
[PexMethod]
public void UpdateTest([PexAssumeUnderTest]ItemUpdater target, Item item) {
PexAssume.IsNotNull(item);
target.Update(item);
var testable = item;
PexObserve.ValueAtEndOfTest("Quantity", testable.Quantity);
}
}
This will generate the code to test the parameters.