lundi 30 mars 2015

Trouble with Mock.Assert() for sequential calls with different argument values to mock

Could someone please take a look at the demo code below and let me know if what I'm seeing is due to error on my part or a Telerik issue?


I'm using Telerik.JustMock v. 2014.1.1519.1. and Microsoft.VisualStudio.QualityTools.UnitTestFramework v. 10.0.0.0.


As the code comments note, I get the expected results when the id variables are equal (one call for each of the ids), but not when they're different. When I step through the first test I can see the expected calls being made, but JustMock then tells me they weren't made.


I'll appreciate any constructive thoughts. Hopefully this isn't a case of me not getting enough sleep...



[TestClass]
public class RunnerTests
{
[TestMethod]
public void MakeTwoCallsDifferentIdsFails()
{
int idOne=1;
int idTwo=2;

DataTable dt=new DataTable();
dt.Columns.Add("Id");
dt.Rows.Add(idOne);
dt.Rows.Add(idTwo);

IProcessor mock = Mock.Create<IProcessor>();
Runner runner = new Runner(mock);
runner.Process(dt);

Mock.Assert(()=>mock.Process(Arg.IsAny<MyArgs>()), Occurs.Exactly(2));
//The following two asserts fail (with 0 calls made to mock), regardless of sequence:
Mock.Assert(()=>mock.Process(Arg.Matches<MyArgs>
(d=>d.Id==idOne)),Occurs.Once());
Mock.Assert(()=>mock.Process(Arg.Matches<MyArgs>
(d=>d.Id==idTwo)),Occurs.Once());
}

[TestMethod]
public void MakeTwoCallsSameIdPasses()
{
//ids intentionally equal:
int idOne=1;
int idTwo=1;

DataTable dt=new DataTable();
dt.Columns.Add("Id");
dt.Rows.Add(idOne);
dt.Rows.Add(idTwo);

IProcessor mock = Mock.Create<IProcessor>();
Runner runner = new Runner(mock);
runner.Process(dt);

//all asserts pass:
Mock.Assert(()=>mock.Process(Arg.IsAny<MyArgs>()), Occurs.Exactly(2));
//The following two pass:
Mock.Assert(()=>mock.Process(Arg.Matches<MyArgs>
(d=>d.Id==idOne)),Occurs.Exactly(2));
Mock.Assert(()=>mock.Process(Arg.Matches<MyArgs>
(d=>d.Id==idTwo)),Occurs.Exactly(2));
}
}

public interface IProcessor
{
void Process(MyArgs args);
}

public class MyArgs
{
public void UpdateId(int newId)
{
this.Id = newId;
}

public int Id {get; private set;}
}

public class Runner
{
private IProcessor processor;

public Runner(IProcessor processor)
{
this.processor=processor;
}

public void Process(DataTable dt)
{
MyArgs args = new MyArgs();

foreach(DataRow row in dt.Rows)
{
int id = Convert.ToInt32(row["Id"]);
args.UpdateId(id);
processor.Process(args);
}
}
}


EDIT: In the test method that fails, if I completely remove one of the int variables and explicitly assert that the other was called exactly once, the test passes. Things seem to go south only when I throw that second, different value into the mix.


Aucun commentaire:

Enregistrer un commentaire