I wanted to have a test case where I can verify a list of IRule count increases as new IRule item added. The method I am testing is AddRule. I wanted to keep the 'rules' property private.
Here's the code
public class DefaultRulesManager : IRulesManager
{
private List<IRule> rules;
public DefaultRulesManager()
{
rules = new List<IRule>();
}
public void AddRule(IRule rule)
{
if (rule == null)
{
throw new ArgumentNullException("rule must be set");
}
rules.Add(rule);
}
public bool HasPassed<T, SKU>(T obj, SKU s)
{
IProduct product = (IProduct)obj;
return rules.All(x => x.HasPassed(product, s));
}
}
You could expose a Count read only property that returns the count of rules:
public int RulesCount
{
get { return rules.Count; }
}
There are various options here:
Expose rules publicly but safely, e.g. via a ReadOnlyCollection<T> wrapper or as an IEnumerable<IRule> via return rules.Select(r => r); to avoid the actual list being exposed via casting. This is reasonable if you have no objection to callers knowing what rules are in a manager, so long as they can't modify the list except via AddRule.
Expose rules internally (ideally via a property - I wouldn't suggest an internal field; I'd also make the field readonly), and use InternalsVisibleTo to allow your test access to that. (You could expose just the count if you want, but I'm not sure it's particularly beneficial.)
Stick to testing the public API - you can check whether all the rules you add into the list (in your test) are then consulted.
Personally I'd probably go for the former option - but some people take "only test the public API" as a golden rule never to be broken.
Yet another idea, on the top of previous answers is to perform your unit tests against a class which inherits DefaultRulesManager.
You'd have to change DefaultRulesManager class slightly by making rules member protected. Inherited class can be named DefaultRulesManagerTestable and provide public readonly property RulesCount which would return rules.Count.
Related
I am getting started with c#. I am asked to do an assignement that contains writing a unit test for a setter and checking its output. I don't follow the meaning of testing something very trivial that does not contain any logic. here's the example (SetKeywords() is the method to be tested):
public struct Keyword
{
private string keyword;
private KeywordTypes type;
public Keyword(string keyword, KeywordTypes Type =
KeywordTypes.String)
{
this.keyword = keyword;
this.type = Type;
}
public string GetString()
{
return this.keyword;
}
public KeywordTypes WhichType()
{
return this.type;
}
}
public class ShopParser
{
private Keyword[] keywords = new Keyword[0];
public void **SetKeywords**(Keyword[] tags)
{
keywords = tags;
}
}
public Keyword[] GetKeywords()
{
return this.keywords;
}
public static KeywordPair[] ExtractFromTaG(ShopParser parser, string
serializedInput)
{
var findings = new KeywordPair[0];
foreach (var keyword in parser.GetKeywords())
{
var start = serializedInput.IndexOf(keyword.GetStart());
// Check if keyword is in input string, if not continue
with next keyword.
if (start <= -1) continue;
var end = serializedInput.LastIndexOf(keyword.GetEnd());
// Extract the thing between the tags. Tag excluded
start += keyword.GetStart().Length;
var substring = serializedInput.Substring(start, end -
start);
// Add substring to result list
var tmp = new KeywordPair[findings.Length + 1];
var i = 0;
for (; i < findings.Length; ++i)
{
tmp[i] = findings[i];
}
tmp[i] = new KeywordPair(keyword, substring);
findings = tmp;
}
return findings;
}
}
Lack of complex code does not mean there are no design decisions by the author of the class that should be verified and protected by unit tests. I.e. the fact you picked value type for items in the collection makes some behaviors impossible and some trivial - the test are there to clarify that class implements that design decision properly and protects the behavior of the class in case of future modifications.
Unit tests for setters for properties of a collection type (unlike value type int) are actually non trivial because one must verify that contract of the class is defined and properly supported - does setter make a copy of a collection or reference existing one, does it make deep or shallow copy? Testing each of the cases properly is definitely not a trivial task. (Same to lesser extent applies to all reference type properties, but in non-collection cases expectations of behavior are usually more aligned with default).
So what you want to do before writing the test is to decide the behavior of your collection property - does it make copy at the moment of setting or refers to the original live instance. If collection would be of reference type (not the case in the question) you also need to decide if it takes shallow or deep copy (deep copy is unusual).
After you made the decision it is somewhat trivial to write the test to verify. You add following tests:
is the collection exposed via getter has the same items in the same order as one used to call setter (applies to both copy and reference approaches)
use setter with a collection and modify original collection (in case of an array change items in the collection). Verify that the collection exposed by the getter behaves properly (either matches updated one for live reference or stays the same for copied one)
if using collection of non-immutable reference types verify that modifying individual items behave as expected (either reflects modification for non-deep copy or stays the same)
if collection just refers to original one tests may be shortened to just checking for reference equality between the original and value returned by the getter, but doing so will not document expected behavior and limit ability to modify in the future.
One may need additional test to validate that collection returned as result of the getter behaves as designed by the class author - in particular if modification of the resulting collection are reflected in the class' state or not (getter returning shallow/deep copy of the state or just exposing internal state directly as shown in the question).
Please note that it is discouraged to have setters for collection properties - see CA2227: Collection properties should be read only. So code in the question sort of follows the recommendation but better name like "AddKeywords"/"ReplaceKeywords" would clarify behavior rather than general "set".
How to test?
When you call SetKeywords, it should do something. Right now it sets the internal array keywords. So the question you need to ask yourself is how can you be sure it did that? Well you have a GetKeywords method which returns the internal array so we can use that to conduct our tests as below:
[TestClass]
public class ShopParserTests
{
[TestMethod]
public void SetKeyWords__WhenGivenAnArray__MustSetTheInternalArray()
{
// Arrange
var k1 = new Keyword("One", KeywordTypes.String);
var k2 = new Keyword("Two");
var parser = new ShopParser();
var keys = new Keyword[] { k1, k2 };
// Act
parser.SetKeywords(keys);
// Assert
Keyword[] keysReturned = parser.GetKeywords();
Assert.AreEqual(keysReturned[0].GetString(), k1.GetString());
Assert.AreEqual(keysReturned[0].WhichType(), k1.WhichType());
Assert.AreEqual(keysReturned[1].GetString(), k2.GetString());
Assert.AreEqual(keysReturned[1].WhichType(), k2.WhichType());
// More tests
}
}
Some Suggestions
Keep in mind that you may need to write a lot more tests based on your requirements. For example, what if the user does this:
Keyword[] keysReturned = parser.GetKeywords();
keys[0] = new Keyword();
Do you want to allow that?
Also, in C# your classes can be simplified and take advantage of properties. So your Keyword and ShopParser classes be written like this:
public struct Keyword
{
public Keyword(string keyword, KeywordTypes type =
KeywordTypes.String)
{
this.TheKeyword = keyword;
this.KeyType= type;
}
public string TheKeyword { get; private set; }
public KeywordTypes KeyType { get; private set; }
}
public class ShopParser
{
public void SetKeywords(Keyword[] tags)
{
this.KeyWords = tags;
}
public Keyword[] KeyWords { get; private set; }
}
Please feel free to modify the title, I couldn't come up with any better one =\
Given the following example class
public class Person
{
public string Name;
public int ID;
public string City;
}
I need to create another mirror class, where every field is actually a wrapper of the original class:
public class PersonMirror
{
public FieldWrapper<string> Name;
public FieldWrapper<int> ID;
public FieldWrapper<string> City;
}
public class FieldWrapper<T>
{
public T Value;
public bool someBool;
public int someCounter;
// ..whatever
}
The thing is, I have many classes to mirror, and some of them have many fields! Moreover, the original class may be changed from time to time (add / remove / rename field), and every change must be applied to the mirrored class - not a good practice for maintainability.
My question is - is there a type safe way automate the decleration (rather then creation, such as generated code) of such mirrored classes?
EDIT:
Let's start from the beginning. In our SOA system, there is a resource access service (serviceX) responsible for updating items in the DB. Other services send it the modifications they would like to perform - in json that would be something like: {ID: 123, name : "myNewName"}. serviceX would then build an update query to send to the DB. However, there is a requirement that serviceX will expose a POCO interface, so that the interface will be language independent, so expressions such as (p=> p.name, "MyNewName") are not allowed. Another requirement is type safety, so json is not allowed either. Currently, the above solution is the best one we came up to answer all the requirements. Any better solutions are more then welcome!
IMO, there's no way to do what you want, except code generation.
Approaches for code generation could differ (this maybe source code generation + compilation, emitting IL code, either your own or existing one), but this is the only way.
use T4 to autogenerate your "WrapperClass".
Below, a proposition of how you could implement your FieldWrapper.
public class FieldWrapper<T, O>
{
private T _item;
private O _owner;
private PropertyInfo _setter;
public T Value
{
get { return _item; }
set {
if (!EqualityComparer<T>.Default.Equal(_item, value))
{
_item = value;
// do some personal check
_setter.SetValue(_owner, value);
}
}
}
public bool someBool;
public int someCounter;
// ..whatever
// CTOR
public FieldWrapper(O owner, Expression<Func<T, O>> propertyExpressionInTheOwner)
{
_owner = owner;
propertyName = (propertyExpressionInTheOwner.body as MemberExpression).Member.Name;
// get PropertyInfo using the owner and propertyName
}
}
Using the expression behavior permits you to create your fieldWrapper this way.
var p = new Person();
new FieldWrapper(p, (pers) => pers.Name);
The good point with this technique it is that if you person class change you will directly receive a compilation error.
With T4 the must is to load the assembly where all you class are, tag you class model with a specific attribute. Look into the assembly to found every class that have this attribute and generate the wrapper class associate.
You would have to run it after every code change, but you could create a code parsing application.
List desired keywords to substitute, such as " string ", " int ". Read the file, line by line. Find definition of classes (line contains "class"), then replace every instance of any given keyword in it with:
"FieldWrapper<" + keyword + ">"
You might want to drop keyword substitution inside methods (and perhaps in the method signatures / return types themselves) of by checking for "(" and ")", and the opening curly brace. Resume operation when you reach the closing curly brace. You can achieve that by storing the nesting level in an integer, incrementing it when hitting '{' and decrementing it when reaching '}'.
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 Primitive class and use a generator, you can mock the generator. An example:
I've changed Primitive to use a provided generator. In this case it's set to a static variable, and there are better ways, but as an example:
public abstract class Primitive
{
internal static IPrimitiveIDGenerator Generator;
protected Primitive()
{
Id = Generator.GetNext();
}
internal int Id { get; private set; }
}
public interface IPrimitiveIDGenerator
{
int GetNext();
}
public class PrimitiveIDGenerator : IPrimitiveIDGenerator
{
private int? _previousId;
public int GetNext()
{
try
{
_previousId = checked(++_previousId) ?? 0;
return _previousId.Value;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
}
Then, your test case becomes:
[Fact(DisplayName = "Test Primitive count limit")]
public void TestPrimitiveCountLimit()
{
Assert.Throws(typeof(OverflowException), delegate()
{
var generator = new PrimitiveIDGenerator();
for (; ; )
{
generator.GetNext();
}
});
}
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:
public void Does_primitive_ask_for_an_ID()
{
var generator = new Mock<IPrimitiveIDGenerator>();
// Set the expectations on the mock so that it checks that
// GetNext is called. How depends on what mock framework you're using.
Primitive.Generator = generator;
new ChildOfPrimitive();
}
Now you have separated the different concerns and can test them separately.
The point of the mock is to simulate an external resource. It's not what you want, you want to test your object, no mock needed in this szenario. Just instantiate the 2 billion objects if you like to, it doesn't hurt since the GC will throw away the old instances (but may take a while to complete).
Id' actually add another constructor which accepts a strarting value for the identity counter, so that you can actually start close to int.MaxValue and therefore don't need to instatiate as many objects.
Also, just from readin the source I can tell that your object will fail the test. ;-)
You have two problems baked into this question:
How to unit test an abstract class, that you can't instantiate.
How to efficiently unit test functionality that requires two billion instances to be created and destroyed.
I think the solutions are pretty simple, even though you'll have to re-think the structure of your object slightly.
For the first problem, the solution is as simple as adding a fake that inherits Primitive, but adds no functionality, to your test project. You can then instantiate your fake class instead, and you'll still be testing the functionality of Primitive.
public class Fake : Primitive { }
// and in your test...
Assert.Throws(typeof(OverflowException), delegate() { var f = new Fake(int.MaxValue); });
For the second problem, I'd add a constructor that takes an int for the previous ID, and use constructor chaining to "not need it" in your actual code. (But how to you get to know of the previous id otherwise? Can't you set that to int.MaxValue-1 in the setup of your test?) Think of it as dependecy injection, but you're not injecting anything complex; you're just injecting a simple int. It could be something along these lines:
public abstract class Primitive
{
internal int Id { get; private set; }
private static int? _previousId;
protected Primitive() : Primitive([some way you get your previous id now...])
protected Primitive(int previousId)
{
_previousId = previousId;
try
{
_previousId = Id = checked (++_previousId) ?? 0;
}
catch (OverflowException ex)
{
throw new OverflowException("Cannot instantiate more than (int.MaxValue) unique primitives.", ex);
}
}
All has been said in the other answers. I just want to show you an alternative, maybe this is somehow interesting for you.
If you made the _previousId field of your Primitive class internal (and included the respective InternalsVisibleTo attribute, of course), then your test could be as simple as this with the Typemock Isolator tool:
[Fact(DisplayName = "Test Primitive count limit"), Isolated]
public void TestPrimitiveCountLimit()
{
Primitive._previousId = int.MaxValue;
Assert.Throws<OverflowException>(() =>
Isolate.Fake.Instance<Primitive>(Members.CallOriginal, ConstructorWillBe.Called));
}
Sure, Typemock comes with some license costs, but it definitely makes life much easier and saves you a lot of time, if you have to write large amounts of test code - especially on systems which are not easily tested or are even impossible to test with a free mocking framework.
Thomas
I swear I have seen an example of this but have been googling for a bit and can not find it.
I have a class that has a reference to an object and need to have a GET; method for it. My problem is that I do not want anyone to be able to fiddle with it, i.e. I want them to get a read only version of it, (note I need to be able to alter it from within my class).
Thanks
No, there's no way of doing this. For instance, if you return a List<string> (and it's not immutable) then callers will be able to add entries.
The normal way round this is to return an immutable wrapper, e.g. ReadOnlyCollection<T>.
For other mutable types, you may need to clone the value before returning it.
Note that just returning an immutable interface view (e.g. returning IEnumerable<T> instead of List<T>) won't stop a caller from casting back to the mutable type and mutating.
EDIT: Note that apart from anything else, this kind of concern is one of the reasons why immutable types make it easier to reason about code :)
Return a reference to a stripped-down interface:
interface IFoo
string Bar { get; }
class ClassWithGet
public IFoo GetFoo(...);
If the object isn't too complicated/extensive then write an wrapper around it.
for example:
class A {
public string strField = 'string';
public int intField = 10;
}
class AWrapper {
private A _aObj;
public AWrapper(A aobj) {
_aObj = A;
}
public string strField {
get {
return _aObj.strField;
}
}
public int intField {
get {
return _aObj.intField;
}
}
}
So now all you do is give your client code an instance of the AWrapper class so that they may only use what you allow them to see.
this may get a bit complicated and may not scale well if your base class is not set in stone, but for most simple situation it may just do the trick. I think this is called a facade pattern(but don't quote me on that =) )
This isn't possible. Get and set accessors to reference types get and set the reference to the object. You can prevent changes to the reference by using a private (or internal) setter, but you cannot prevent changes to the object itself if it's exposed by a getter.
Your question reads like you're looking for:
public PropertyName { get; private set; }
But then, given the answers so far I'm not sure I'm interpreting your question correctly. Besides, who am I to question Jon Skeet? :)
i agree with ReadOnlyCollection
See my simple code:
private List<Device> _devices;
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices
{
get
{
return (_devices.AsReadOnly());
}
}
ReadOnlyCollection dosen't has Add method so user cant add properties to it.BUT ther is no warranty that if user can modify objects by calling their methods....
I have faced this problem in a certain way.
I have a CategoryViewModel class, which have a property Category that I want private read-only :
public CategoryViewModel
{
private Category { get; }
}
In fact, I want it to be exported as read-only to other class. However I can't do such thing.
In my case (maybe it will help some other guys), I want to add it to a repository. The only way that I've found is to have a function with the repository as param 1, and an Action as param 2 :
public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action)
{
action(repo, Category);
}
Like that, from elsewhere, I can do such thing :
categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c));
This can help other to expose there property only for certains cases and can manage them.
Its typical to expose internal data structures as properties to your business class. But when we have to expose array-like structures (like List<Rule> rules) we might encounter a problem of wrong usage (as in Option 1).
Its suggested to expose clone of such data structures as properties, so that internal structure does not get disturbed.
Does any one have a well-settled solution for this?
public class Rule
{
}
public class RulesManager
{
List<Rule> rules = new List<Rule>();
public List<Rule> Rules
{
get { return rules; }
set { rules = value; }
}
public void Add(Rule r)
{
rules.Add(r);
// Do something else after add;
}
public void Delete(Rule r)
{
rules.Remove(r);
// Do something else after delete;
}
}
public class CallingCode
{
public static void Main()
{
RulesManager r = new RulesManager();
// Option 1
r.Rules.Add(new Rule());
// Option 2
r.Add(new Rule());
}
}
Instead of returning a Clone, you can return a read-only version of rules using rules.AsReadOnly().
public IList<Rule> Rules
{
get { return rules.AsReadOnly(); }
// set { rules = value; -- should not be allowed to set if read only!
}
Note the IList.
Instead of returning a List you can return an IEnumerable. The IEnumerable allows the user to iterate through the collection, but it doesn't allow the user to modify it easily.
Alternatively you could return an arryay instead of a list. This will create a copy of the list that the user cannot easily modify.
Finally you should be aware that the user might also modify the contents of the collection. This may be what you want, but you might also want to return copies of your items.
I think it is quite common to expose the IList as a property, but I prefer to expose only explicit Add/Delete functions. You can also consider to implement one of the collection interfaces in your class (IList for instance), if you are developing something more of a framework.
Instead of:
public List<Rule> Rules
{
get { return rules; }
set { rules = value; }
}
I prefer to implement IEnumerable<T> and an indexer on the class, so that I have control over what happens to the list.
Check out the ReadOnlyCollection and the AsReadOnly() List method.
A basic workaround is to use List<T>.AsReadOnly() method, which will wrap the list around a ReadOnlyCollection to block any "write" access. Of course, you'd have to make the setter private, otherwise it would not make sense...
Another alternative would be to implement your own IList that would alert you in case of "write" access and allow you to perform your business logic.