I use Vs2015 with NSubstitute 3.1.0.
This code is passed but shouldn't.
public class Test
{
public string[] Content { get; set; }
}
[Fact]
public void Should_What()
{
var obj = Substitute.For<Test>();
var test = obj.DidNotReceive().Content;
var test2 = obj.Received().Content;
}
If replace class Test to interface it will works well, but in my test I have class.
How to check if property Content has been used ?
The solution is to use virtual for the property.
public virtual string[] Content { get; set; }
But, if two opposing tests return the True at the same time, we have a bug.
Can explain why and indicate a solution, but this is a workaround.
In my opinion it should throw an exception (ex. NotSupportedException, when a test is executed on non-virtual properties).
The testing environment is expected to detect the problems. So it should be pessimistic.
In this case should be better to return false instead of true. To sign the developer the problem (even if it is in the framework).
For example in SQL when try to check null value, will always return false (null == true, null == 0 or even null == null).
This is just my point.
What do you guys think about it?
Related
I'm pretty new to programming, and I'm teaching myself. Any and all help is appreciated, but please be understanding -- I don't really know what I'm doing that well. Also, this is the first question I've ever posted on SO (I sure have read a lot of other people's, so thanks for all that), so if I need to modify anything about how I'm asking, please let me know. Thanks!
I'm working on creating a Xamarin application in Visual Studio.I created a mock database to serve mock information to my application. The MockDatabase file is a POCO with static lists to hold the information. There are 11 lists for the models that I created that will eventually map to the SQLite database file I'm planning to use in the future. Here's a snapshot of the file:
public class MockDatabase : IDataStore
{
public static List<tblAddress> Addresses { get; set; }
public static List<tblCrew> Crews { get; set; }
public static List<tblCustomer> Customers { get; set; }
public static List<tblEmployee> Employees { get; set; }
//etc...
public MockDatabase(bool createMockData = false)
{
if (createMockData)
{
Addresses = Addresses ?? MockData.MockAddresses();
Crews = Crews ?? MockData.MockCrews();
Customers = Customers ?? MockData.MockCustomers();
Employees = Employees ?? MockData.MockEmployee();
//etc...
}
}
The static modifier does what I want, that even if I initialize multiple instances of the class, each of them points to the same static instance of the list. So, the problem that I'm having with using static lists is that it works too well. When I run my unit tests in a consecutive run, the tests are getting the data that a previous test set, which meant I had to rewrite the tests to account for this. I solved the problem by calling MockDatabase.Addresses = new List<tblAddress>(); in my test initialization, but I really wanted to use something that would work more broadly, and not need to be specialized for each test class that I'm creating.
Here's what I had written:
[TestClass]
public class AddressRepositoryTests
{
[TestInitialize]
public virtual void SetUp()
{
MockDatabase.Addresses = new List<tblAddress>();
}
But what I was trying to accomplish was to have the MockDatabase use some reflection to find all lists within itself and reset their value. I tried a number of variations on the following code, but I couldn't find anything that worked.
[TestClass]
public class AddressRepositoryTests
{
[TestInitialize]
public virtual void SetUp()
{
(new MockDatabase()).ClearDatabase();
}
public void ClearDatabase()
{
var properties = typeof(MockDatabase).GetProperties();
foreach (var property in properties)
{
if (property.PropertyType == typeof(IList<BaseModel>))
{
property.SetValue(this, null);
}
}
}
I put a break point inside the if statement and tried a number of different code variations, and nothing ever returned true.
Thanks for any help!
Edit
I don't know how to use the generic List<T> in the middle of a method. Sticking it into the line produces the compiler error "The type or namespace T could not be found..."
if (property.PropertyType == typeof(IList<T>)) //Will not compile
I also tried comparing against List<object>, but that fails too.
if (property.PropertyType == typeof(IList<object>)) //Fails
Could you try changing ClearDatabase function as below:
public void ClearDatabase()
{
var properties = typeof(MockDatabase).GetProperties();
foreach (var property in properties)
{
if (property.PropertyType.Name == typeof(List<>).Name || property.PropertyType.Name == typeof(IList<>).Name)
{
property.SetValue(this, null);
}
}
}
I have a method that searches something in my database according to a field. when calling that method and saving the returning value in a variable, the returning value is not null at the end of the function. After the function has been called and I debug what is available in my variable, the value is still null!
In one class I have:
var box = _someClass.GetBoxByRfidAsync("testvalue");
public Box GetBoxByRfidAsync(string rfid)
{
var foundBox = _dc.Boxes
.Include(b => b.Stack)
.Include(b => b.Type)
.Where(box => box.RFID1 == rfid)
.FirstOrDefault();
return foundBox;
}
The box class looks like this:
public class Box
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string RFID1 { get; set; }
public string Rit { get; set; }
public Stack Stack { get; set; }
public int PosInStack { get; set; } //lowest box is 0, highest is 7
public BoxType Type { get; set; }
public DateTime Inserted { get; set; }
}
The method gets executed and at the end of GetBoxByRfidAsync I can see using the debugger that foundBox is NOT null.
I step over the end of the function and go to the assignment of the foundBox value to the box variable. For some reason the 'box' variable stays null and does not change.
The box variable should be equal to the foundBox value, but it stays null.
Here are some screenshots of my debugging session:
The error you show in the debugger doesn't mean that box is null. If box was null, it would literally just report: null.
Instead, the box is non-null, and something that the debugger is evaluating to display the value is throwing an exception. Perhaps a broken ToString(). The fact that it mentions ListDictionaryInternal means that you might want to look in particular at any collection or dictionary usage inside the type, and perhaps anything that is marked with "debugger" attributes such as [DebuggerDisplay(...)].
If you want to test whether box is null, ask the immediate console:
box == null
and it will return true or false (caveat: assuming that there isn't a broken static equality operator, which is also possible; to avoid that, a good alternative is:
box is object
which will reliably return true if it is non-null, and false if it is null, without using static equality operators.
Edit: based on the discussion in the comments, I'm overwhelmingly convinced that this is a broken == operator, as demonstrated here:
I have the following class:
public class OrderRule {
public OrderDirection Direction { get; }
public String Property { get; }
}
I created an Unit Test using XUnit as follows:
public void TryParse_ParseAscendingOrderRule() {
OrderRule expect = new OrderRule("name", OrderDirection.Ascending);
OrderRule result = factory.GetOrderRule("type1");
Assert.Equal(result, expect);
}
I know expect and result have the same Direction and Property values but I still get False on my test ... I suppose this is because they are not the same instance ...
Do I really need to compare the Direction and Property as follows?
Assert.True(result.Property == expect.Property && expect.Property == expect.Property );
This can become really long when the objects have many properties ...
Or is there a better way to do this?
If it is not necessary for OrderRule to be a class then make it a struct which by default implements value equality. There is also a whole MSDN page about value equality which might help you.
I am trying to understand why mocking behaves in such a way (I'm using NUnit with Moq). Let's say, we have a simple class:
public class Package
{
public virtual int PackageId { get; set; }
public Package()
:this(-1)
{
}
public Package(int packageId)
{
PackageId = packageId;
}
}
And some simple tests to discuss:
[TestFixture]
public class NUnitTrickyTest
{
private const int SamplePackageId = 10;
[Test]
public void TestPackageSetUp_WhenMockedWithDefaultConstructor_ExpectSamplePackageIdSet()
{
var samplePackage = new Mock<Package>();
samplePackage.SetupProperty(x => x.PackageId, SamplePackageId);
Assert.AreEqual(SamplePackageId, samplePackage.Object.PackageId);
}
[Test]
public void TestPackageSetUp_WhenMockedWithParametrizedConstructor_ExpectSamplePackageIdSet()
{
var samplePackage = new Mock<Package>(SamplePackageId);
// samplePackage.SetupProperty(x => x.PackageId, SamplePackageId);
Assert.AreEqual(SamplePackageId, samplePackage.Object.PackageId);
}
}
The first test fails as samplePackage.Object.PackageId returns -1, not 10 as expected. As I understand mocked Package() calls parameterized constructor which initializes the property with default -1. In the second test we find samplePackage.Object.PackageId returning 0.
The first thing I don't understand why 0 was returned (in debug I saw that 10 was passed in the constructor, but the property remained 0 value). The second one: if we uncomment this command samplePackage.SetupProperty(x => x.PackageId, SamplePackageId) in the second test, it will succeed. So why SetupProperty behaves as expected in that case (property returns 10), and not in such a way in the first test?
Could you please help? This is my first post so don't be severe :)
All mockable (virtual) methods use a proxy by default, so that is why you get a default value (0) on the second test (the proxy is not set). You can get around this by setting CallBase = true on your mock, though.
CallBase = true will use default implementations if available instead of trying to mock everything out.
It took me a second to figure out the reason for the first one failing and I believe that this is because SetupProperty only turns on tracking with a default value and since you are overriding that default value in the constructor then that is what is used. If you want to force a value then you need to use Setup(x=>x.PackageId).Returns(SamplePackageId) or SetupGet
In C# I'm writing a class that checks the values of its properties with a setter method:
private int _grade
public int Grade {
get { return _grade;}
set { if (value >= this.lowerLimit) _grade = value; }
}
I would like to signal to the application if a value was rejected. I had considered refactoring to use a setGrade function that returns a bool (accepted / rejected) but the ability to do someInstance.Grade++ and someInstance.Grade*=2 are important. Simple functions incrementGrade and divideGrade will make the code a mess, and there will certainly be some function that I forgot to implement (too much coupling).
My current solution is to check the value of someInstance.Grade after setting it, to ensure that it has been set. But it seems to me that this is just moving the mess from the class to the application. Indeed, it is the responsibility of the application to ensure that the value was properly set.
How do those more experienced handle this? Thanks!
It is indeed caller's responsibility to set values that make sense.
Normally, it is accepted practice to throw ArgumentOutOfRangeException in the setter when the value is wrong. If the caller expects possibly wrong value (e.g. user input), it can catch the right exception.
private int _grade
public int Grade {
get { return _grade;}
set {
if (value < lowerLimit) {
throw new ArgumentOutOfRangeException("value",
string.Format("Grade must be higher than or equal to {0}.", lowerLimit)
);
}
_grade = value; // will not happen if the exception was thrown
}
}
There is also ArgumentNullException for null values when you don't want them, and general ArgumentException if your argument rejection reason is different from these two cases.
A more hip approach would be to use Code Contracts as suggested by Jean-Bernard.
However this feature is still somewhat new and not widely used in .NET projects.
Code Contracts add static analysis so you discover such errors at compilation stage.
They will still throw ArgumentExceptions in runtime, though.
You could use Code Contracts
Here is an answer to another question which has more resources: link
Most of the time, I either silently adjust the value given to be within the range of values, or throw an Exception, depending on the situation.
Another option: you could make an event PropertyValueRejected that your class's clients could subscribe to:
public class PropertyValueRejectedEventArgs {
public string PropertyName { get; set; }
public object RejectedValue { get; set; }
}
public class MyClass {
public event EventHandler<PropertyValueRejectedEventArgs> PropertyRejected;
private int _grade = -1;
public int Grade {
get { return _grade; }
set {
if (value >= this.lowerLimit) {
_grade = value;
}
else if (PropertyRejected != null) {
PropertyRejected(
this,
new PropertyValueRejectedEventArgs {
PropertyName = "Grade",
RejectedValue = value
}
);
}
}
}
}