Check the new value of a variable in an action

0

I have the following piece of code from a unit test:

[Test]
public void ValidCancel_ReturnsSuccess()
{
    // TODO: Rewrite this action to really check the cancel
    bool cancel;
    var message =
        new MessageHubCancellableGenericMessage<string>(this, "Test", () => cancel = true);

    Assert.IsNotNull(message.Sender);
    Assert.IsNotNull(message.Content);
}

MessageHubCancellableGenericMessage is a constructor that receives a sender , a content and a Action to perform as arguments. In the third argument I am changing the variable cancel to true . The detail here is that if I want to do a Assert.IsTrue of the variable it brings false . Is there a way to check that change in the variable, or is it not possible?

This is the class I'm trying:

using System;

public abstract class MessageHubMessageBase : IMessageHubMessage
{
    private readonly WeakReference _sender;

    protected MessageHubMessageBase(object sender)
    {
        if (sender == null)
            throw new ArgumentNullException(nameof(sender));

        _sender = new WeakReference(sender);
    }

    public object Sender => _sender?.Target;
}

public class MessageHubGenericMessage<TContent>
    : MessageHubMessageBase
{
    public MessageHubGenericMessage(object sender, TContent content)
        : base(sender)
    {
        Content = content;
    }

    public TContent Content { get; protected set; }
}

public class MessageHubCancellableGenericMessage<TContent> 
    : MessageHubMessageBase
{
    public MessageHubCancellableGenericMessage(object sender, TContent content, Action cancelAction)
        : base(sender)
    {
        Content = content;
        Cancel = cancelAction ?? throw new ArgumentNullException(nameof(cancelAction));
    }

    public Action Cancel { get; protected set; }

    public TContent Content { get; protected set; }
}
    
asked by ArCiGo 30.11.2017 в 19:14
source

2 answers

2

Do you want to know if the value was changed before calling the Assert?

You can place breakpoints after the call to the constructor, and you can inspect the value of the Cancel variable.

Do you want to know if it enters the Action and at what moment? you can change from:

var message =
    new MessageHubCancellableGenericMessage<string>(
        this, "Unosquare Américas", 
        () => cancel = true);

a:

var message =
    new MessageHubCancellableGenericMessage<string>(
        this, "Unosquare Américas", 
        () => 
        {  // <-- coloca un punto de iterrupción aquí
            cancel = true; 
        });

And the execution of the program is going to pause there, and with F10 you can move instruction by instruction to see the value of cancel.

EDIT : By the way, I do not see at what point, in the code, you throw the action call.

I do not know if you forgot to put that part of the code, but I think it would be something like this:

public class MessageHubCancellableGenericMessage<TContent> : MessageHubMessageBase
{
    public MessageHubCancellableGenericMessage(object sender, TContent content, Action cancelAction) : base(sender)
    {
        Content = content;
        Cancel = cancelAction ?? throw new ArgumentNullException(nameof(cancelAction));

        Cancel(); // <--- esta línea debe ir donde quieres llamar al action
    }

    public Action Cancel { get; protected set; }

    public TContent Content { get; protected set; }
}

I still did not understand the purpose of the Action.

    
answered by 30.11.2017 в 23:48
-1
  

Is there a way to check that change in the variable, or is it not possible?

Yes, it's with Assert.IsTrue , just like you did.

  

The detail here is that if I want to do a Assert.IsTrue of the variable it brings false .

This is because cancel never goes to true .

  

In the third argument I am changing the variable cancel to true .

No, and here is the problem. In the third argument you are passing code to it in the form of a Action that, if someone were to execute it , then it would change the variable to true . But nobody executes it. If we examine the constructor code of class MessageHubCancellableGenericMessage<TContent> :

public class MessageHubCancellableGenericMessage<TContent> 
    : MessageHubMessageBase
{
    public MessageHubCancellableGenericMessage(object sender, TContent content, Action cancelAction)
        : base(sender)
    {
        Content = content;
        Cancel = cancelAction ?? throw new ArgumentNullException(nameof(cancelAction));
    }

    public Action Cancel { get; protected set; }

    public TContent Content { get; protected set; }
}

... we can see that the Action cancelAction parameter is assigned to the Cancel property. But there is nothing that executes the Action , so that the statement cancel = true is never executed.

If you want it to run, in order to later check that the variable cancel changed, you must add a call to message.Cancel() in your unit test:

[Test]
public void ValidCancel_ReturnsSuccess()
{
    // TODO: Rewrite this action to really check the cancel
    bool cancel;
    var message =
        new MessageHubCancellableGenericMessage<string>(this, "Test", () => cancel = true);

    // Esta sentencia cambia cancel a true.
    message.Cancel();

    // Ahora sí puedes verificar que la variable cambió
    Assert.IsTrue(cancel);

    Assert.IsNotNull(message.Sender);
    Assert.IsNotNull(message.Content);
}
    
answered by 01.12.2017 в 01:03