I was hoping that by using AutoFixture and NSubstitue, I could use the best of what each have to provide. I have had some success using NSubstitute on its own, but I am completely confused on how to use it in combination with AutoFixture.
My code below shows a set of things I am trying to accomplish, but my main goal here is to accomplish the following scenario: Test the functionality of a method.
- I expect the constructor to be called with random values (except maybe one - please read point 2.).
- Either during construction or later, I want to change value of a property -
Data
. - Next call
Execute
and confirm the results
The test that I am trying to get working is: "should_run_GetCommand_with_provided_property_value"
Any help or reference to an article that shows how NSubstitue and AutFixture SHOULD be used, would be great.
Sample Code:
using FluentAssertions;
using NSubstitute;
using Ploeh.AutoFixture;
using Ploeh.AutoFixture.AutoNSubstitute;
using Xunit;
namespace RemotePlus.Test
{
public class SimpleTest
{
[Fact]
public void should_set_property_to_sepecified_value()
{
var sut = Substitute.For<ISimple>();
sut.Data.Returns("1,2");
sut.Data.Should().Be("1,2");
}
[Fact]
public void should_run_GetCommand_with_provided_property_value()
{
/* TODO:
* How do I create a constructor with AutoFixture and/or NSubstitute such that:
* 1. With completely random values.
* 2. With one or more values specified.
* 3. Constructor that has FileInfo as one of the objects.
*
* After creating the constructor:
* 1. Specify the value for what a property value should be - ex: sut.Data.Returns("1,2");
* 2. Call "Execute" and verify the result for "Command"
*
*/
// Arrange
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
// var sut = fixture.Build<Simple>().Create(); // Not sure if I need Build or Freeze
var sut = fixture.Freeze<ISimple>(); // Note: I am using a Interface here, but would like to test the Concrete class
sut.Data.Returns("1,2");
// Act
sut.Execute();
// Assert (combining multiple asserts just till I understand how to use NSubstitue and AutoFixture properly
// sut.Received().Execute();
sut.Data.Should().Be("1,2");
sut.Command.Should().Be("1,2,abc");
// Fails with : FluentAssertions.Execution.AssertionFailedExceptionExpected string to be "1,2,abc" with a length of 7, but "" has a length of 0.
}
}
public class Simple : ISimple
{
// TODO: Would like to make this private and use the static call to get an instance
public Simple(string inputFile, string data)
{
InputFile = inputFile;
Data = data;
// TODO: Would like to call execute here, but not sure how it will work with testing.
}
// TODO: Would like to make this private
public void Execute()
{
GetCommand();
// Other private methods
}
private void GetCommand()
{
Command = Data + ",abc";
}
public string InputFile { get; private set; }
public string Data { get; private set; }
public string Command { get; private set; }
// Using this, so that if I need I can easliy switch to a different concrete class
public ISimple GetNewInstance(string inputFile, string data)
{
return new Simple(inputFile, data);
}
}
public interface ISimple
{
string InputFile { get; } // TODO: Would like to use FileInfo instead, but haven't figured out how to test. Get an error of FileNot found through AutoFixture
string Data { get; }
string Command { get; }
void Execute();
}
}
I'm posting this as a separate answer because it's more a critique of approach, than direct answer to your original question. In my other answer I've tried to directly answer your AutoFixture/NSubstitute questions assuming that you are currently trying to learn these to frameworks.
As it stands, you don't really need to use either of these frameworks to achieve what you are doing and in some ways it's easier not to. Looking at this test:
This isn't actually testing your class at all (other than compilation checks), really you're testing NSubstitute. You're checking that if you tell NSubstitute to return a value for a property that it does.
Generally speaking, try to avoid mocking the class that you're testing. If you need to do it, then there is a good chance that you need to rethink your design. Mocking is really useful for supplying dependencies into your class that you can control in order to influence the behaviour of your class. If you start modifying the behaviour of the class you're testing using mocks then it's very easy to get confused about what you're actually testing (and to create very brittle tests).
Because you're dealing with basic types and not nested objects, at the moment it's easy to create + test your objects without using something like AutoFixture/NSubstitute. You code could look like this, which seems to be closer to what you're hoping for:
And your test would look like this:
I've left the
Execute
outside of the objects constructor because it feels a bit like it's going to be doing too much. I'm not a huge fan of doing a lot other than basic setup in constructors particularly if there's a chance you might end up calling virtual methods. I've also madeGetNewInstance
static so that it can be called directly (otherwise you have to create aSimple
to callGetNewInstance
on it which seems wrong)...Whilst I've shown above how your code could work as you want it so, I'd suggest that you might want to change the
Simple
constructor to internal, rather than private. This would allow you to create a factory to create the instances. If you had something like this:This allows you to safely constructor objects that need methods called on them. You can also inject substitutes of the
IMyObjectFactory
that returns a substitute ofISimple
in future classes that are dependent on theSimple
class. This helps you to isolate your classes from the underlying class behaviour (which might access the file system) and makes it easy for you to stub responses.