Is there some kind of way to let AutoFixture create properties with an internal setter?
I've looked at the AutoFixture source and found that in the AutoPropertiesCommand the GetProperties method checks whether a property has GetSetMethod() != null.
With an internal setter this returns null, unless you set the ignorePublic argument to true.
The easiest thing would of course be to make the setter public but in the project I'm working on this just wouldn't be the right solution.
Below is a simplified piece of code from the project as an example.
public class Dummy
{
public int Id { get; set; }
public string Name { get; internal set; }
}
public class TestClass
{
[Fact]
public void Test()
{
var dummy = new Fixture().Create<Dummy>();
Assert.NotNull(dummy.Name);
}
}
Ideally, the tests shouldn't have to interact with the internal members of a class, since they are explicitly excluded from its public API. Instead, these members would be tested indirectly by the code paths initiated through the public API.
However, if this isn't feasible in your particular situation, a possible workaround could be to explicitly assign a value to the internal properties from within the tests.
You can do that in one of two ways:
By exposing all internal members within the assembly to the test project using the InternalsVisibleTo attribute.
By representing the modifiable state of the class in a specific interface and implement that explicitly.
In your example, option 1 would be:
// [assembly:InternalsVisibleTo("Tests")]
// is applied to the assembly that contains the 'Dummy' type
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
dummy.Name = fixture.Create<string>();
// ...
}
Option 2, instead, would be something like:
public class Dummy : IModifiableDummy
{
public string Name { get; private set; }
public void IModifiableDummy.SetName(string value)
{
this.Name = value;
}
}
[Fact]
public void Test()
{
var fixture = new Fixture();
var dummy = fixture.Create<Dummy>();
((IModifiableDummy)dummy).SetName(fixture.Create<string>());
// ...
}
Option 1 is fairly quick to implement, but has the side effect of opening up all internal members within the assembly, which may not be what you want.
Option 2, on the other hand, allows you to control what part of the object's state should be exposed as modifiable, while still keeping it separated the object's own public API.
As a side note, I'd like to point out that, since you're using xUnit, you can take advantage of AutoFixture's support for Data Theories to make your tests slightly more terse:
[Theory, AutoData]
public void Test(Dummy dummy, string name)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}
If you prefer to set the Name property to a known value while still keeping the rest of the Dummy object anonymous, you have also the possibility to combine the two within the same Data Theory:
[Theory, InlineAutoData("SomeName")]
public void Test(string name, Dummy dummy)
{
((IModifiableDummy)dummy).SetName(name);
// ...
}
Related
I want to write a nunit test to test a method but I am not able to mock an object instantiated inside that method.
Here is the code:
public class Converter()
{
public void modifyScore(string convertTo){
ScoreConverter scoreConverter;
if(convertTo.Equals("decimal"){
scoreConverter = new DecimalScoreConverter();
scoreConverter.determineScore();
}
else{
scoreConverter = new IntegerScoreConverter();
scoreConverter.determineScore();
}
}
I want to write a test for modifyScore and want to test which object's method has called.
How can I test this method using nunit?
First of all you should start working against abstractions.
I think this is needed for all mock frameworks.
From the info you gave me, and a couple of assumptions:
Anyway, here we go:
public Interface IConverter
{
IScoreConverter ScoreConverter { get; set; };//use constructorinjection instead
void ModifyScore(string convertTo);
}
public Interface IScoreConverter
{
DetermineScore();
}
I would recommend taking a look at MoQ.
You need to figure out what you want to be returned by the inner object.
For now you don't return any value from ModifyScore, so you have nothing to test.
If you would return e.g. a string, the test could look like this:
var scoreConverterResponse = "theStringYouWantToBeReturned"
var scoreConverterMock = new Mock<IScoreConverter>();
scoreConverterMock.Setup(sc => sc.DetermineScore())
.Returns(scoreConverterResponse);
scoreConverterMock.Verify(sc => sc.DetermineScore(It.IsAny<string>()), Times.AtLeastOnce());
I fixed the naming conventions toom i.e. CamelCase methods.
I wrote this on the fly, so I apologise if there are compile errors.
Unit tests are mostly based on state change. So, the natural course is to:
Do something on a class
Test whether the state of the class changed as expected
Maybe you can consider a change in your code to test the type of scoreConverter:
public class Converter
{
public ScoreConverter scoreConverter { get; set; }
public void modifyScore(string convertTo){
if(convertTo.Equals("decimal"){
scoreConverter = new DecimalScoreConverter();
}
else{
scoreConverter = new IntegerScoreConverter();
}
scoreConverter.determineScore();
}
Your test can then execute the modifyScore() method, and then Assert the type of scoreConverter variable.
If you don't want to make the property public, another option is to make it internal and then add the InternalsVisibleToAttribute, or maybe to use a Factory class and then mock it in the test, as amcdermott pointed out.
Greetings!
I'm not sure this is what it's called, but here's what I'm trying to achieve:
I need to be able to specify an Attribute to properties, fields and classes, and every time an object with the [Attribute] specified will call a certain static function.
I already know how to set up the attribute, but I'm not sure how to go about intercepting the creation of every object and calling the function on it.
You cannot intercept an object being created without inserting some sort of code into the class itself, or creating a Factory around the class to manage instantiation.
Assuming you have a class like this:
public class MyData
{
[Captialization]
public string Name { get; set; }
}
With an attribute defined like this:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Class)]
public class CaptializationAttribute : Attribute { }
You can detect and manipulate the properties tagged with various attributes like this:
public static class DataUtilities
{
public static void ApplyAttributes<T>(T obj)
{
// Capitalization attribute
var props = typeof (T).GetProperties().Where(p => p.GetCustomAttributes(typeof (CaptializationAttribute), true).Any());
foreach (var prop in props)
{
// This is just an example, if you use this code you
// should check if the property is a string first!
prop.SetValue(obj, prop.GetValue(obj).ToString().ToUpper());
// Or perform some other manipulation here.
}
}
}
Now, to invoke this code automatically, you need to decide when you want it to occur. If it's well after the instantiation, you'll likely have to call it yourself from somewhere. But if it's during instantiation, you can do one of two things:
Using a Factory:
public static class MyDataFactory
{
public static MyData Create()
{
var myData = new MyData();
DataUtilities.ApplyAttributes(myData);
return myData;
}
}
You'll likely want to use an internal constructor to prevent outside instantiation.
// No instantiation from outside the assembly
internal MyData() { }
Using the constructor:
Add the call to the manipulation utility into your constructor:
public MyData()
{
DataUtilities.ApplyAttributes(this);
}
There are other methods of doing this, such as using a Proxy, Dependency Injection, or as #Yuval Itzchakov mentioned, an AOP framework, but the ones I described are probably the easiest to implement.
I am trying to mock the ManagementObjectSearcher class and have created a IManagementInfo interface, so how can i cast the interface to the ManagementObjectSearcher class?
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info = s as IManagementInfo;
this creates me a null info object
ManagementObjectSearcher s = new ManagementObjectSearcher();
IManagementInfo info =IManagementInfo(s);
this gives me run time error (cannot typecast)
You cannot do that. Do you want to do it so that you can write unit tests? If you are trying to mock a class that you have no control of, then you have to wrap it in another class.
public class MyManagementObjectSearcherWrapper : IManagementInfo
{
public void TheMethodToMock()
{
var searcher = new ManagementObjectSearcher();
// The code you want to mock goes here
}
}
And you run your code like this:
public void YourCode(IManagementInfo info)
{
info.TheMethodToMock();
}
Then YourCode() will take either your wrapper or the mocked object. You create your mock using the IManagementInfo interface.
It looks as if you are trying to wrap a 3rd party/system object in order to aid unit testing.
Say that your starting point is
public class Dependency {
public string Foo() {
return "foo"; // machine, system, time, something else, dependent result
}
public string Bar() {
return "bar";
}
}
public class MySimpleClass {
public string MyFunc() {
return new Dependency().Foo();
}
}
[TestMethod]
public void TestSimple() {
var client = new MySimpleClass();
Assert.AreEqual("foo", client.MyFunc());
}
We are creating the Dependency inside the call because we are considering the creation cost to be less important than holding on to an instance of the Dependency. This will be dependent upon the situation. We could as easily have created a Dependency in the ctor and stored a copy which we invoked each time. Either way, we have no control over the output which makes unit testing messy.
We need to create a proxy for it.
1. Define an interface for the members that we need
Most likely, we do not need to use all of the members of the wrappee so only include in the interface those about which we care.
public interface IDependencyProxy {
string Foo();
}
2. Create a Proxy Class
We then create a proxy class wrapping the dependency and implementing interface. Again, we can create at start or on a call by call basis.
public class DependencyProxy : IDependencyProxy {
public string Foo() {
return new Dependency.Foo();
}
}
3. Define our client code in terms of the interface
We modify our client code slightly to use the IDependencyProxy interface instead of the Dependency. There are a few ways of doing this. I generally use an internal ctor which takes the dependency chained from a public ctor. (Use [InternalsVisibleTo] to allow the unit tests to see it)
public class MyRevisedClass {
private readonly IDependencyProxy dependency;
public MyRevisedClass()
: this( new DependencyProxy()) {}
internal MyRevisedClass(IDependencyProxy dependency) {
this.dependency = dependency;
}
public string MyFunc() {
return dependency.Foo();
}
}
This allows us a default behaviour for the production code (invokes the System object) and allows us to mock out the results for unit testing.
[TestMethod]
public void TestRevisedDefault() {
var client = new MyRevisedClass();
Assert.AreEqual("foo", client.MyFunc());
}
[TestMethod]
public void TestRevisedWithMockedDependency() {
var dep = new Mock<IDependencyProxy>();
dep.Setup(mk => mk.Foo()).Returns("bar");
var client = new MyRevisedClass(dep.Object);
Assert.AreEqual("bar", client.MyFunc());
}
I have designed an immutable class, because I want to have value-semantics for it. I wrote a hint into the commentary section of the class
// "This class is immutable, don't change this when adding new features to it."
But I know, sometimes those commentaries are overlooked by other team members, so I would like to create a unit test as an additional safeguard. Any idea how to accomplish this? Can one inspect a class via reflection to make sure only the constructors change it's inner state?
(Using C# 2.0 and NUnit, if that's important for anyone).
An example to back up my comment on how you can use FieldInfo.IsInitOnly recursively to test for immutability.
There may be more special cases to consider like how I have handled string, but it will only give false negatives I believe, i.e. will tell you something is mutable that is not, not the other way around.
The logic is, every field must be readonly and be an immutable type itself. Note that it will not cope with self referential types or circular references.
using System;
using System.Linq;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace ImmutableTests
{
[TestClass]
public class AssertImmutableTests
{
[TestMethod]
public void Is_int_immutable()
{
Assert.IsTrue(Immutable<int>());
}
[TestMethod]
public void Is_string_immutable()
{
Assert.IsTrue(Immutable<string>());
}
[TestMethod]
public void Is_custom_immutable()
{
Assert.IsTrue(Immutable<MyImmutableClass>());
}
[TestMethod]
public void Is_custom_mutable()
{
Assert.IsFalse(Immutable<MyMutableClass>());
}
[TestMethod]
public void Is_custom_deep_mutable()
{
Assert.IsFalse(Immutable<MyDeepMutableClass>());
}
[TestMethod]
public void Is_custom_deep_immutable()
{
Assert.IsTrue(Immutable<MyDeepImmutableClass>());
}
[TestMethod]
public void Is_propertied_class_mutable()
{
Assert.IsFalse(Immutable<MyMutableClassWithProperty>());
}
private static bool Immutable<T>()
{
return Immutable(typeof(T));
}
private static bool Immutable(Type type)
{
if (type.IsPrimitive) return true;
if (type == typeof(string)) return true;
var fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
var isShallowImmutable = fieldInfos.All(f => f.IsInitOnly);
if (!isShallowImmutable) return false;
var isDeepImmutable = fieldInfos.All(f => Immutable(f.FieldType));
return isDeepImmutable;
}
}
public class MyMutableClass
{
private string _field;
}
public class MyImmutableClass
{
private readonly string _field;
}
public class MyDeepMutableClass
{
private readonly MyMutableClass _field;
}
public class MyDeepImmutableClass
{
private readonly MyImmutableClass _field;
}
public class MyMutableClassWithProperty
{
public string Prop { get; set; }
}
}
You could check that the class is sealed, and using reflection check that each field is read-only (using FieldInfo.IsInitOnly).
Of course, that only ensures shallow immutability - it wouldn't stop someone from putting a List<int> field in there, and then changing the contents of the list.
Not sure if you've heard of NDepend, but this tool allows you to "introspect" over your source code and compiled assemblies and do all sorts of magic including dependency checking and much more.
One such check is a check for immutability. For instance, I have an IImmutable marker interface, and NDepend fails my build if any types have this interface but are mutable, using the following query:
WARN IF Count > 0 IN SELECT TYPES WHERE
Implement "MyCompany.MyAssemblies.Dto.IImmutable" AND
!IsImmutable
You can also configure it to generate violation reports, as well as failing builds.
Obviously this isn't actually a unit test. However, it can be integrated as part of your build, and fail your build just as a unit test would, so I thought I'd mention it!
See here for more info on what it actually does and how.
I have an immutable class with some private fields that are set during the constructor execution. I want to unit test this constructor but I'm not sure the "best practice" in this case.
Simple Example
This class is defined in Assembly1:
public class Class2Test
{
private readonly string _StringProperty;
public Class2Test()
{
_StringProperty = ConfigurationManager.AppSettings["stringProperty"];
}
}
This class is defined in Assembly2:
[TestClass]
public class TestClass
{
[TestMethod]
public void Class2Test_Default_Constructor()
{
Class2Test x = new Class2Test();
//what do I assert to validate that the field was set properly?
}
}
EDIT 1: I have answered this question with a potential solution but I'm not sure if it's the "right way to go". So if you think you have a better idea please post it.
This example isn't really worth testing, but assume the constructor has some more complex logic. Is the best approach to avoid testing the constructor and to just assume it works if all the tests for the methods on the class work?
EDIT 2: Looks like I made the sample a little to simple. I have updated it with a more reasonable situation.
Nothing, unless you are using that field. You don't want over-specification via tests. In other words, there is no need to test that the assignment operator works.
If you are using that field in a method or something, call that method and assert on that.
Edit:
assume the constructor has some more complex logic
You shouldn't be performing any logic in constructors.
Edit 2:
public Class2Test()
{
_StringProperty = ConfigurationManager.AppSettings["stringProperty"];
}
Don't do that! =) Your simple unit test has now become an integration test because it depends on the successful operation of more than one class. Write a class that handles configuration values. WebConfigSettingsReader could be the name, and it should encapsulate the ConfigurationManager.AppSettings call. Pass an instance of that SettingsReader class into the constructor of Class2Test. Then, in your unit test, you can mock your WebConfigSettingsReader and stub out a response to any calls you might make to it.
I have properly enabled [InternalsVisibleTo] on Assembly1 (code) so that there is a trust relationship with Assembly2 (tests).
public class Class2Test
{
private readonly string _StringProperty;
internal string StringProperty { get { return _StringProperty; } }
public Class2Test(string stringProperty)
{
_StringProperty = stringProperty;
}
}
Which allows me to assert this:
Assert.AreEqual(x.StringProperty, "something");
The only thing I don't really like about this is that it's not clear (without a comment) when you are just looking at Class2Test what the purpose of the internal property is.
Additional thoughts would be greatly appreciated.
In your edit, you now have a dependancy on ConfigurationManager that is hard to test.
One suggestion is to extract an interface to it and then make the Class2Test ctor take an IConfigManager instance as a parameter. Now you can use a fake/mock object to set up its state, such that any methods that rely on Configuration can be tested to see if they utilize the correct values...
public interface IConfigManager
{
string FooSetting { get; set; }
}
public class Class2Test
{
private IConfigManager _config;
public Class2Test(IConfigManager configManager)
{
_config = configManager;
}
public void methodToTest()
{
//do something important with ConfigManager.FooSetting
var important = _config.FooSetting;
return important;
}
}
[TestClass]
public class When_doing_something_important
{
[TestMethod]
public void Should_use_configuration_values()
{
IConfigManager fake = new FakeConfigurationManager();
//setup state
fake.FooSetting = "foo";
var sut = new Class2Test(fake);
Assert.AreEqual("foo", sut.methodToTest());
}
}