So basically, I have an abstract class which has a unique, incremental ID – Primitive. When a Primitive (or more precisely, an inheritor of Primitive) is instantiated, the ID is incremented – up to the point where the ID overflows – at which point, I add a message to the exception and rethrow.
OK, that all works fine… but I’m trying to test this functionality and I’ve never used mocking before. I just need to make enough Primitives for the ID to overflow and assert that it throws at the right time.
- It is unreasonable to instantiate 2 billion objects to do this! However I don’t see another way.
- I don’t know if I’m using mocking correctly? (I’m using
Moq.)
Here’s my test (xUnit):
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
for (; ; )
{
var mock = new Mock<Primitive>();
}
});
}
and:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive()
{
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
I assume I’m doing it wrong – so how do I test this properly?
You don’t need mocking for this. You use mocking when two classes work together and you want to replace one class with a mock (fake) one so you only have to test the other one. This is not the case in your example.
There is however a way you could use mocks, and that fixes your issue with the 2bln instances. If you separate the ID generation from the
Primitiveclass and use a generator, you can mock the generator. An example:I’ve changed
Primitiveto use a provided generator. In this case it’s set to a static variable, and there are better ways, but as an example:Then, your test case becomes:
This will run a lot faster and now you’re only testing whether the ID generator works.
Now, when you e.g. want to test that creating a new primitive actually asks for the ID, you could try the following:
Now you have separated the different concerns and can test them separately.