user9630194
user9630194

Reputation: 398

How to mock txt output?

I have a txt which the logic can access through a repository. I want to determine that when I call Write method from logic, the repositorys Write method is called once. My code:

    [Test]
    public void TestThatWriteWasCalledOnce()
    {
        Mock<IRepository> mockinstance = new Mock<IRepository>();
        LogicSaveGame logic = new LogicSaveGame(mockinstance.Object);
        //mockinstance.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).  //???
        logic.Write(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>());
        mockinstance.Verify(x => x.Write(It.IsAny<string>(), It.IsAny<string>()), Times.Once());
    }

When I run the test above I get the error:

Message: 
System.ArgumentNullException : Value cannot be null.
Parameter name: value
Stack Trace: 
XAttribute.ctor(XName name, Object value)

I'm really grateful for any help, couldn't find anything with google.

Edit, logicsavegame:

    private readonly IRepository saveGameRepo;

    public LogicSaveGame(IRepository repo)
    {
        this.saveGameRepo = repo;
    }

    public void Write(string name, string a, string b, string filename)
    {
        int ids = this.saveGameRepo.GetIds(filename);
        var xd = new XElement(
            "game",
            new XAttribute("id", ids + 1),
            new XAttribute("name", name),
            new XAttribute("hour", DateTime.Now.Hour),
            new XAttribute("minute", DateTime.Now.Minute),
            new XElement(
            "player1",
            new XElement("name", a.Name),
            new XElement(
            "player2",
            new XElement("name", b.Name),
            ));
        this.saveGameRepo.Write(filename, xd.ToString());
    }

Edit 2: I get the same error with mockinstance.Setup(x => x.Write(It.IsAny(), It.IsAny())).Verifiable();

Upvotes: 1

Views: 74

Answers (2)

Iliar Turdushev
Iliar Turdushev

Reputation: 5213

TL;DR

To fix your problem pass to method call logic.Write concrete string values, for example:

logic.Write("name", "a", "b", "filename");

Explanation

The problem is not in mocking IRepository. The problem is how you call method logic.Write. You pass parameters to it using It.IsAny<string>(). Method It.IsAny<string>() returns null value, therefore during execution your method logic.Write is called with the next values:

logic.Write(null, null, null, null);

Inside method logic.Write you create XAttribute("name", name). Documentation says that this constructor requires both its parameters to be not null. In the test it is called with null value of the name variable therefore an exception System.ArgumentNullException : Value cannot be null is thrown that points to the constructor XAttribute.ctor(XName name, Object value). Therefore to fix the problem it is neccessary to pass to method logic.Write non-null string values.

Upvotes: 1

jsami
jsami

Reputation: 356

I smell you forgot to set up your mock correctly before calling your LogicSaveGame (which is saving to XML file apparently). You may refer to this link.

Upvotes: 0

Related Questions